15

a長さが等しくないベクトルを含むリストと のベクトルbからのいくつかの要素を含むベクトルが与えられた場合、 の要素が一致する場所のインデックスaを含む に等しい長さのベクトルを取得したい(これは私が知っている悪い説明です)...bab

次のコードはその仕事をします:

a <- list(1:3, 4:5, 6:9)
b <- c(2, 3, 5, 8)

sapply(b, function(x, list) which(unlist(lapply(list, function(y, z) z %in% y, z=x))), list=a)
[1] 1 1 2 3

sapplyをfor ループに置き換えると、もちろん同じことが達成されます

問題は、このコードが 1000 を超える長さのリストとベクトルで使用されることです。実際のセットでは、関数は約 15 秒かかります (for ループと の両方sapply)。

並列アプローチで安全に、これを高速化する方法を知っている人はいますか? 私はベクトル化されたアプローチを目にすることができませんでした (C でプログラミングすることはできませんが、それがおそらく最も速いでしょう)。

編集:

1667 倍 (15 から 0.009) のオーダーで速度が向上した match() を使用した Aaron のエレガントなソリューションを強調します。

複数の一致を許可するために少し拡張しました(戻り値はリストです)

a <- list(1:3, 3:5, 3:7)
b <- c(3, 5)
g <- rep(seq_along(a), sapply(a, length))
sapply(b, function(x) g[which(unlist(a) %in% x)])
[[1]]
[1] 1 2 3

[[2]]
[1] 2 3

この実行時間は 0.169 で、これは間違いなくかなり遅いですが、一方でより柔軟です。

4

2 に答える 2

16

を使用した 1 つの可能性を次に示しmatchます。

> a <- list(1:3, 4:5, 6:9)
> b <- c(2, 3, 5, 8)
> g <- rep(seq_along(a), sapply(a, length))
> g[match(b, unlist(a))]
[1] 1 1 2 3

findInterval別のオプションです:

> findInterval(match(b, unlist(a)), cumsum(c(0,sapply(a, length)))+1)
[1] 1 1 2 3

リストを返すには、これを試してください:

a <- list(1:3, 4:5, 5:9)
b <- c(2,3,5,8,5)
g <- rep(seq_along(a), sapply(a, length))
aa <- unlist(a)
au <- unique(aa)
af <- factor(aa, levels=au)
gg <- split(g, af)
gg[match(b, au)]
于 2012-06-12T18:18:42.110 に答える
0

あなたの投稿へのコメントが示唆するように、同じ要素がa. あなたができる最低のインデックスが欲しいと仮定すると:

apply(sapply(a, function(vec) {b %in% vec}), 1, which.max)
于 2012-06-12T19:36:32.607 に答える