14

いくつかのベクトルのリストがあります。リスト内のすべてのベクトルが等しいかどうかを確認したいと思います。identicalペアごとの比較でのみ機能するものがあります。だから私は醜いように見える次の関数を書きました。それでも、より良い解決策が見つかりませんでした。これが私のREです:

test_true <- list(a=c(1,2,3),b=c(1,2,3),d=c(1,2,3))
test_false <- list(a=c(1,2,3),b=c(1,2,3),d=c(1,32,13))

compareList <- function(li){
  stopifnot(length(li) > 1)
  l <- length(li)
  res <- lapply(li[-1],function(X,x) identical(X,x),x=li[[1]])
  res <- all(unlist(res))
  res
}

compareList(test_true)
compareList(test_false)

助言がありますか?ペアごとの比較以上の同一のネイティブチェックはありますか?

4

6 に答える 6

22

どうですか

allSame <- function(x) length(unique(x)) == 1

allSame(test_true)
# [1] TRUE
allSame(test_false)
# [1] FALSE

@JoshuaUlrichが以下で指摘したように、uniqueリストでは遅いかもしれません。また、異なる基準を使用する場合もありますidentical。は、ペアワイズ操作を拡張するために最近学んだ関数です。uniqueReduce

identicalValue <- function(x,y) if (identical(x,y)) x else FALSE
Reduce(identicalValue,test_true)
# [1] 1 2 3
Reduce(identicalValue,test_false)
# [1] FALSE

これは、不一致が 1 つ見つかった後も比較を続ける非効率的です。それに対する私の大まかな解決策は、エラーをスローするelse break代わりに書くことです。else FALSE

于 2013-09-15T14:39:39.817 に答える
6

解決策をまとめます。テストのデータ:

x1 <- as.list(as.data.frame(replicate(1000, 1:100)))
x2 <- as.list(as.data.frame(replicate(1000, sample(1:100, 100))))

ソリューション:

comp_list1 <- function(x) length(unique.default(x)) == 1L
comp_list2 <- function(x) all(vapply(x[-1], identical, logical(1L), x = x[[1]]))
comp_list3 <- function(x) all(vapply(x[-1], function(x2) all(x[[1]] == x2), logical(1L)))
comp_list4 <- function(x) sum(duplicated.default(x)) == length(x) - 1L

データのテスト:

for (i in 1:4) cat(match.fun(paste0("comp_list", i))(x1), " ")
#> TRUE  TRUE  TRUE  TRUE   
for (i in 1:4) cat(match.fun(paste0("comp_list", i))(x2), " ")
#> FALSE  FALSE  FALSE  FALSE  

ベンチマーク:

library(microbenchmark)
microbenchmark(comp_list1(x1), comp_list2(x1), comp_list3(x1), comp_list4(x1))
#> Unit: microseconds
#>            expr      min        lq      mean   median        uq      max neval cld
#>  comp_list1(x1)  138.327  148.5955  171.9481  162.013  188.9315  269.342   100 a  
#>  comp_list2(x1) 1023.932 1125.2210 1387.6268 1255.985 1403.1885 3458.597   100  b 
#>  comp_list3(x1) 1130.275 1275.9940 1511.7916 1378.789 1550.8240 3254.292   100   c
#>  comp_list4(x1)  138.075  144.8635  169.7833  159.954  185.1515  298.282   100 a  
microbenchmark(comp_list1(x2), comp_list2(x2), comp_list3(x2), comp_list4(x2))
#> Unit: microseconds
#>            expr     min        lq      mean   median        uq      max neval cld
#>  comp_list1(x2) 139.492  140.3540  147.7695  145.380  149.6495  218.800   100  a 
#>  comp_list2(x2) 995.373 1030.4325 1179.2274 1054.711 1136.5050 3763.506   100   b
#>  comp_list3(x2) 977.805 1029.7310 1134.3650 1049.684 1086.0730 2846.592   100   b
#>  comp_list4(x2) 135.516  136.4685  150.7185  139.030  146.7170  345.985   100  a

duplicatedおよびunique関数に基づく最も効率的なソリューションをご覧ください。

于 2016-02-07T07:30:19.713 に答える
6

私はそうします:

all.identical <- function(l) all(mapply(identical, head(l, 1), tail(l, -1)))

all.identical(test_true)
# [1] TRUE
all.identical(test_false)
# [1] FALSE
于 2013-09-15T16:44:00.093 に答える
0

cgwtools::approxeq 基本的には何をするall.equalが、等しいかどうかを示す論理値のベクトルを返す私の自己宣伝的な提案を入れます。

したがって、正確な同等性が必要か、浮動小数点表現の同等性が必要かによって異なります。

于 2013-09-15T16:31:40.780 に答える