【发布时间】:2013-04-20 18:38:19
【问题描述】:
让我们考虑两个矩阵A和B。A是B的子集。如何在矩阵B中找到A的每一行的索引? 这是一个可复制的示例:
set.seed(30)
B <- matrix(rnorm(n =30,mean = 0), ncol=3)
A <- subset(B, B[,1] > 1)
目标是找到索引idx,在本例中给出第 4 行和第 5 行。
【问题讨论】:
让我们考虑两个矩阵A和B。A是B的子集。如何在矩阵B中找到A的每一行的索引? 这是一个可复制的示例:
set.seed(30)
B <- matrix(rnorm(n =30,mean = 0), ncol=3)
A <- subset(B, B[,1] > 1)
目标是找到索引idx,在本例中给出第 4 行和第 5 行。
【问题讨论】:
嵌套的apply 循环应该这样做。
apply(A, 1, function(a)
which(apply(B, 1, function(b) all(b==a)))
)
# [1] 4 5
或者,使用colSums
apply(A, 1, function(a)
which(colSums(t(B) == a) == ncol(B)))
# [1] 4 5
【讨论】:
或者,您可以这样做:
transform(A, idx = 1 * duplicated(rbind(A, B))[-seq_len(nrow(A))])
一个很好的解决方案,最初由@Arun 提供。
【讨论】:
> match(apply(A, 1, paste, collapse="\b"), apply(B, 1, paste, collapse="\b"))
[1] 4 5
【讨论】:
这采用了一种稍微不同的方法,并且依赖于矩阵是向量这一事实,如果你有data.frames,它将无法工作:
which( B %in% A , arr.ind=TRUE )[1:nrow(A)]
#[1] 4 5
如果您有非常大的矩阵并且想提高一点效率,您可以在子集上使用%in%,如下所示:
which( B[1:nrow(B)] %in% A[1:nrow(A)] , arr.ind=TRUE )
但我不认为这会产生太大的影响,除非在非常大的矩阵中。
如果您的数据为 data.frames,您可以通过仅将第一列传递给 which 来做同样的事情:
A <- data.frame(A)
B <- data.frame(B)
which( B$X1 %in% A$X1 )
#[1] 4 5
【讨论】: