如何在R中找到相等的列?

jon*_*alv 4 r equivalence

鉴于以下内容:

a <- c(1,2,3)
b <- c(1,2,3)
c <- c(4,5,6)
A <- cbind(a,b,c)
Run Code Online (Sandbox Code Playgroud)

我想找到A中的哪些列等于例如我的向量a.

我的第一次尝试是:

> which(a==A)
[1] 1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)

哪个没有那样做.(老实说,我甚至不明白它做了什么)第二次尝试是:

a==A
        a    b     c
[1,] TRUE TRUE FALSE
[2,] TRUE TRUE FALSE
[3,] TRUE TRUE FALSE
Run Code Online (Sandbox Code Playgroud)

这肯定是朝着正确方向迈出的一步,但似乎扩展到了一个矩阵.我更喜欢的是像其中一行一样的东西.如何将矢量与列进行比较,如何在矩阵中找到等于矢量的列?

had*_*ley 8

使用identical.这是R的"标量"比较运算符; 它返回单个逻辑值,而不是向量.

apply(A, 2, identical, a)
#    a     b     c 
# TRUE  TRUE FALSE 
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

但请注意,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 
Run Code Online (Sandbox Code Playgroud)

相同也比使用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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您测试的矢量('a')具有任何其他属性(例如名称),则会失败(并且会静默).`c(1,2,3)`与`c(n = 1,m = 2,x = 3)`不同,即使它们的值相同.我担心使用"相同的". (2认同)

Spa*_*man 7

如果添加额外的行:

> A
     a b c  
[1,] 1 1 4 4
[2,] 2 2 5 2
[3,] 3 3 6 1
Run Code Online (Sandbox Code Playgroud)

然后你可以看到这个函数是正确的:

> hasCol=function(A,a){colSums(a==A)==nrow(A)}
> A[,hasCol(A,a)]
     a b
[1,] 1 1
[2,] 2 2
[3,] 3 3
Run Code Online (Sandbox Code Playgroud)

但接受的早期版本不是:

> 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
Run Code Online (Sandbox Code Playgroud)

它返回4,2,1列,因为2匹配1,2,3中的2.