6

次の場合:

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

それはしませんでした。(正直なところ、私はそれが何をしたのかさえ理解していません)2番目の試みは:

a==A
        a    b     c
[1,] TRUE TRUE FALSE
[2,] TRUE TRUE FALSE
[3,] TRUE TRUE FALSE

これは間違いなく正しい方向への一歩ですが、マトリックスに拡張されているようです。私が好んだのは、行の1つだけのようなものです。ベクトルを列と比較するにはどうすればよいですか?また、ベクトルと等しい行列内の列を見つけるにはどうすればよいですか?

4

4 に答える 4

9

を使用しidenticalます。これがRの「スカラー」比較演算子です。ベクトルではなく、単一の論理値を返します。

apply(A, 2, identical, a)
#    a     b     c 
# TRUE  TRUE FALSE 

Aが実際のデータフレームである場合は、マトリックスへの入力を強制するため、sapplyまたはを使用することをお勧めします。vapplyapply

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
于 2012-10-19T12:42:29.913 に答える
8

行を追加する場合:

> 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

2が1,2,3の2と一致するため、4,2,1列を返します。

于 2012-10-19T11:24:22.520 に答える
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
于 2012-10-19T08:50:19.360 に答える
-1
colSums(a==A)==nrow(A)

のリサイクルにより、すべての列がと等しい次元と等しい次元を持つ行列が効果的==に作成されます。各列を合計します。1と0のように動作しますが、に等しい列の合計は行数に等しくなります。この観察結果を使用して、最終的に論理ベクトルへの答えを減らします。aaAcolSumsTRUEFALSEa

編集:

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
于 2012-10-19T09:33:51.337 に答える