鉴于以下内容:
a <- c(1,2,3)
b <- c(1,2,3)
c <- c(4,5,6)
A <- cbind(a,b,c)
我想找到A中的哪些列等于例如我的矢量a。
我的第一次尝试是:
> which(a==A)
[1] 1 2 3 4 5 6
哪个没有那样做。 (老实说我甚至不明白那是做什么的) 第二次尝试是:
a==A
a b c
[1,] TRUE TRUE FALSE
[2,] TRUE TRUE FALSE
[3,] TRUE TRUE FALSE
这肯定是朝着正确方向迈出的一步,但似乎扩展到了一个矩阵。我更喜欢的是像其中一行一样的东西。如何将矢量与列进行比较,如何在矩阵中找到等于矢量的列?
答案 0 :(得分:8)
使用identical
。这是R的“标量”比较运算符;它返回单个逻辑值,而不是向量。
apply(A, 2, identical, a)
# a b c
# TRUE TRUE FALSE
如果A
是您实际情况中的数据框,则最好使用sapply
或vapply
,因为apply
会强制它输入矩阵。
d <- c("a", "b", "c")
B <- data.frame(a, b, c, d)
apply(B, 2, identical, a) # incorrect!
# a b c d
# FALSE FALSE FALSE FALSE
sapply(B, identical, a) # correct
# a b c d
# TRUE TRUE FALSE FALSE
但请注意data.frame
强制要素的字符输入,除非您另有要求:
sapply(B, identical, d) # incorrect
# a b c d
# FALSE FALSE FALSE FALSE
C <- data.frame(a, b, c, d, stringsAsFactors = FALSE)
sapply(C, identical, d) # correct
# a b c d
# FALSE FALSE FALSE TRUE
相同也比使用all
+ ==
快得多:
library(microbenchmark)
a <- 1:1000
b <- c(1:999, 1001)
microbenchmark(
all(a == b),
identical(a, b))
# Unit: microseconds
# expr min lq median uq max
# 1 all(a == b) 8.053 8.149 8.2195 8.3295 17.355
# 2 identical(a, b) 1.082 1.182 1.2675 1.3435 3.635
答案 1 :(得分:7)
如果添加额外的行:
> A
a b c
[1,] 1 1 4 4
[2,] 2 2 5 2
[3,] 3 3 6 1
然后你可以看到这个功能是正确的:
> hasCol=function(A,a){colSums(a==A)==nrow(A)}
> A[,hasCol(A,a)]
a b
[1,] 1 1
[2,] 2 2
[3,] 3 3
但接受的早期版本没有:
> oopsCol=function(A,a){colSums(a==A)>0}
> A[,oopsCol(A,a)]
a b
[1,] 1 1 4
[2,] 2 2 2
[3,] 3 3 1
它返回4,2,1列,因为2匹配1,2,3中的2。
答案 2 :(得分:4)
当然有一个更好的解决方案,但以下工作:
> a <- c(1,2,3)
> b <- c(1,2,3)
> c <- c(4,5,6)
> A <- cbind(a,b,c)
> sapply(1:ncol(A), function(i) all(a==A[,i]))
[1] TRUE TRUE FALSE
获得指数:
> which(sapply(1:ncol(A), function(i) all(a==A[,i])))
[1] 1 2
答案 3 :(得分:-1)
colSums(a==A)==nrow(A)
回收==
会使a
有效地成为一个矩阵,其所有列都等于a
且维度等于A
的列。每列colSums
总和;虽然TRUE
的行为类似于1而FALSE
的行为类似于0,但等于a
的列的总和将等于行数。我们使用这种观察最终减少了逻辑向量的答案。
编辑:
library(microbenchmark)
A<-rep(1:14,1000);c(7,2000)->dim(A)
1:7->a
microbenchmark(
apply(A,2,function(b) identical(a,b)),
apply(A,2,function(b) all(a==b)),
colSums(A==a)==nrow(A))
# Unit: microseconds
# expr min lq median
# 1 apply(A, 2, function(b) all(a == b)) 9446.210 9825.6465 10278.335
# 2 apply(A, 2, function(b) identical(a, b)) 9324.203 9915.7935 10314.833
# 3 colSums(A == a) == nrow(A) 120.252 121.5885 140.185
# uq max
# 1 10648.7820 30588.765
# 2 10868.5970 13905.095
# 3 141.7035 162.858