outer(x, y, FUN)
を使用できます。 x
とy
は数値ベクトル/行列のように "数値"入力である必要はありません。 "list"/"matrix list"のようなベクトル入力も許されます。
は、例えば、我々は、それ自体がベクトル化されていない"%in%"
ため
z <- outer(lst, lst, FUN = Vectorize("%in%", SIMPLIFY = FALSE, USE.NAMES = FALSE))
# vec1 vec2 vec3 vec4
#vec1 Logical,2 Logical,2 Logical,2 Logical,2
#vec2 Logical,3 Logical,3 Logical,3 Logical,3
#vec3 Logical,4 Logical,4 Logical,4 Logical,4
#vec4 Logical,5 Logical,5 Logical,5 Logical,5
を使用ペアワイズ"%in%"
動作を適用するために、我々はVectorized("%in%")
を使用します。 FUN
が各ペアの長さ1リストを返すように、SIMPLIFY = FALSE
も必要です。(x[[i]], y[[j]])
y[[4]] | FUN(x[[1]], y[[4]]) FUN(x[[2]], y[[4]]) FUN(x[[1]], y[[4]]) FUN(x[[2]], y[[4]])
y[[3]] | FUN(x[[1]], y[[3]]) FUN(x[[2]], y[[3]]) FUN(x[[1]], y[[3]]) FUN(x[[2]], y[[4]])
y[[2]] | FUN(x[[1]], y[[2]]) FUN(x[[2]], y[[2]]) FUN(x[[1]], y[[2]]) FUN(x[[2]], y[[4]])
y[[1]] | FUN(x[[1]], y[[1]]) FUN(x[[2]], y[[1]]) FUN(x[[1]], y[[1]]) FUN(x[[2]], y[[4]])
------------------- ------------------- ------------------- -------------------
x[[1]] x[[2]] x[[3]] x[[4]]
それはlength(FUN(x, y)) == length(x) * length(y)
ことを確認しなければならない:outer
作品が好きなように、これは重要です。 SIMPLIFY = FALSE
の場合、これは必ずしも成立しません。
上記の結果z
は「マトリックスリスト」であり、class(z)
は「マトリックス」ですが、typeof(z)
は「リスト」です。詳細はWhy is this matrix not numeric?をご覧ください。
我々はさらにz
の各要素にいくつかの要約機能を適用したい場合は、我々はlapply
を使用することができます。ここでは2つの例を提供します。
例1:any(a %in% b)
のでany()
を適用すなわち、操作が対称である、any(b %in% a)
と同じようで、我々は唯一のz
の下三角で作業する必要があります。
lz <- z[lower.tri(z)]
lapply
名前のないリストを返しますが、読みやすくするために名前付きリストが必要です。私たちは、名前のように行列インデックス(i, j)
を使用することがあります。我々は、同様に動作することができます対称操作も
ind <- which(lower.tri(z), arr.ind = TRUE)
NAME <- paste(ind[,1], ind[,2], sep = ":")
any_lz <- setNames(lapply(lz, any), NAME)
#List of 6
# $ 2:1: logi FALSE
# $ 3:1: logi TRUE
# $ 4:1: logi TRUE
# $ 3:2: logi TRUE
# $ 4:2: logi FALSE
# $ 4:3: logi TRUE
Set操作をintersect
、union
とsetequal
のようなものです。
例2:適用which()
which(a %in% b)
が対称操作ではありませんので、我々は完全な行列と仕事をしなければなりません。
NAME <- paste(1:nrow(z), rep(1:nrow(z), each = ncol(z)), sep = ":")
which_z <- setNames(lapply(z, which), NAME)
# List of 16
# $ 1:1: int [1:2] 1 2
# $ 2:1: int(0)
# $ 3:1: int [1:2] 1 2
# $ 4:1: int 3
# $ 1:2: int(0)
# $ 2:2: int [1:3] 1 2 3
# ...
setdiff
などの設定操作も非対称であり、同様に処理することができます。
代替
別にouter()
を使用してから、我々はまた、上記のz
を得るために、Rの表現を使用することができます。繰り返しますが、私は、一例として、二項演算"%in%"
を取る:
op <- "'%in%'" ## operator
lst_name <- names(lst)
op_call <- paste0(op, "(", lst_name, ", ", rep(lst_name, each = length(lst)), ")")
# [1] "'%in%'(vec1, vec1)" "'%in%'(vec2, vec1)" "'%in%'(vec3, vec1)"
# [4] "'%in%'(vec4, vec1)" "'%in%'(vec1, vec2)" "'%in%'(vec2, vec2)"
# ...
その後、我々はlst
内でこれらの式を解析し、評価することができます。ここではおそらく
NAME <- paste(1:length(lst), rep(1:length(lst), each = length(lst)), sep = ":")
z <- setNames(lapply(parse(text = op_call), eval, lst), NAME)
# List of 16
# $ 1:1: logi [1:2] TRUE TRUE
# $ 2:1: logi [1:3] FALSE FALSE FALSE
# $ 3:1: logi [1:4] TRUE TRUE FALSE FALSE
# $ 4:1: logi [1:5] FALSE FALSE TRUE FALSE FALSE
# $ 1:2: logi [1:2] FALSE FALSE
# ...
ない直接適用はなく、似たようなケースでは、古典的な 'テーブル/(T)crossprod'アプローチは、いくつかのペアごとの関係を明らかにすることができ - ' crossprodを(:私たちは、結果のリストの名の組み合わせのインデックスを使用することができますテーブル(val = unlist(lst、、FALSE)、vec = rep(seq_along(lst)、lengths(lst)))) 'しかし、すべてを集計することで、メモリの限界によって問題が生じる可能性があります –