2016-12-30 41 views
1

有没有简单的方法可以确定一个向量是嵌套在另一个中的?换句话说,在下面的示例中,bar的每个值都与foo中的一个值相关联,因此bar嵌套在foo内。测试一个因子是否嵌套在另一个因子中

data.frame(foo=rep(seq(4), each=4), bar=rep(seq(8), each=2)) 

澄清,这里是理想的结果:

foo <- rep(seq(4), each=4) 
bar <- rep(seq(8), each=2) 
qux <- rep(seq(8), times=2) 
# using a fake operator for illustration: 
bar %is_nested_in% foo # should return TRUE 
qux %is_nested_in% foo # should return FALSE 
+0

你需要'任何(复制(RLE(酒吧)$值))所有(在%RLE(巴FOO%)$值)' – akrun

+0

@! akrun第一部分('!any(duplicated(rle(bar)$ values)')是比我想要的更强的约束。如果'foo'是'c(1,1,1,1,2,2,2,2)'而'bar'是'c(1,2,1,2,3,4,3,4)''那么'bar'仍然会嵌套在'foo' – drammock

回答

4

假设你有两个因素fg,并想知道是否g嵌套在f

方法1:对于谁喜欢的线性代数

考虑两个因素,设计矩阵人:

Xf <- model.matrix(~ f + 0) 
Xg <- model.matrix(~ g + 0) 

如果g嵌套在f,那么Xf列空间必须是子空间的列空间为Xg。换言之,对于Xf的列:y = Xf %*% bf的任何线性组合,可以解决方程式Xg %*% bg = y恰好为

y <- Xf %*% rnorm(ncol(Xf)) ## some random linear combination on `Xf`'s columns 
c(crossprod(round(.lm.fit(Xg, y)$residuals, 8))) ## least squares residuals 
## if this is 0, you have nesting. 

方法2:对于谁喜欢统计人

我们检查应急表:

M <- table(f, g) 

如果所有列只有一个非零项,你有嵌套在fg 。换句话说:

all(colSums(M > 0L) == 1L) 
## `TRUE` if you have nesting 

点评:对于任何方法,你可以很容易地挤码成一条线。

+0

有趣的方法中,我可以看出它为什么会起作用,尽管对于这个特定的问题似乎有点矫枉过正。 – drammock

+0

你编辑的答案有很大的改进,并且更好地解释了它的工作原理。我仍然认为基于线性代数的解决方案是过度的(即产生一个随机的“y”和求解一个线性模型的中间步骤),并且如果你的数据是数字的,并且你忘记了在生成模型矩阵之前调用'factor'。但是,您添加的应急表方法非常简洁并且可以与数字向量一起使用。 – drammock

1

我认为这将工作:

nested_in <- function(b, a) { 
    df <- data.frame(a, b) 
    all(sapply(split(df, df$b), function(i) length(unique(i$a)) < 2)) 
} 

foo <- rep(seq(4), each=4) 
bar <- rep(seq(8), each=2) 
qux <- rep(seq(8), times=2)  

nested_in(bar, foo) # TRUE 
nested_in(qux, foo) # FALSE 
相关问题