在列表中获取匹配索引的快捷方法

Tho*_*P85 15 indexing optimization r list vectorization

给定一个a包含不等长度向量的列表和一个b包含来自向量的元素的向量的列表a,我想得到一个等长的向量来b包含匹配a元素的索引b(这是我所知道的一个不好的解释)...

以下代码完成了这项工作:

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

sapply当然,用for循环替换也可以实现相同的目的

问题是这个代码将用于长度大于1000的列表和向量.在现实生活中,该函数大约需要15秒(for循环和for sapply).

有没有人知道如何加快速度,对并行方法安全?我没有看到矢量化方法(我不能用C编程,尽管这可能是最快的).

编辑:

只会强调Aaron使用match()的优雅解决方案,其速度提升1667次(从15到0.009)

我在它上面扩展了一下以允许多个匹配(返回是一个列表)

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

这个的运行时间是0.169,这可能相当慢,但另一方面更灵活

Aar*_*ica 16

这是一种可能性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
Run Code Online (Sandbox Code Playgroud)

findInterval 是另一种选择:

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

要返回列表,请尝试以下操作:

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