在R中,使用向量化在列表中查找向量的元素

时间:2018-04-06 12:05:40

标签: r vectorization

我有一个矢量v1

v1 = c(1, 200, 4000)

我想在矢量列表L1中找到v1元素的索引,即没有循环,其中

> L1
[[1]]
[1] 1 2 3 4

[[2]]
[1] 100 200 300 400

[[3]]
[1] 1000 2000 3000 4000

输出应为c(1,2,4)。

有没有办法在不使用循环或应用的情况下执行此操作(在计算上与使用循环相同?)我必须为非常长的向量执行此操作。

4 个答案:

答案 0 :(得分:8)

我们可以做到

sapply(L1, function(x) which(x %in% v1))
#[1] 1 2 4

Vectorize

Vectorize(function(x) which(x %in% v1))(L1)
#[1] 1 2 4

如果针对另一个元素的相应元素检查每个元素

mapply(function(x, y) which(x %in% y), L1, v1)
#[1] 1 2 4

正如@nicola提到的,match也可用于获取第一个索引。如果存在重复元素,那么which将非常有用

mapply(match, v1, L1)
#[1] 1 2 4

或使用purrr::map2

purrr::map2_int(L1, v1, ~ .x %in% .y %>%
                                    which)
#[1] 1 2 4

答案 1 :(得分:3)

您可以尝试这样的事情

v1 = c(1, 200, 4000)
L1 <- list(1:4, 1:4*100, 1:4*1000)

setNames(rep(1:length(L1), times=lengths(L1)), unlist(L1))[as.character(v1)]
# 1  200 4000 
# 1    2    3    

答案 2 :(得分:3)

我们可以做到这一点,似乎是迄今为止最快的。

v1 <- c(1, 200, 4000)
L1 <- list(1:4, 1:4*100, 1:4*1000)

sequence(lengths(L1))[match(v1, unlist(L1))]
# [1] 1 2 4
sequence(lengths(L1))[which(unlist(L1) %in% v1)]
# [1] 1 2 4
library(microbenchmark)
library(tidyverse)

microbenchmark(
  akrun_sapply = {sapply(L1, function(x) which(x %in% v1))},
  akrun_Vectorize = {Vectorize(function(x) which(x %in% v1))(L1)},
  akrun_mapply = {mapply(function(x, y) which(x %in% y), L1, v1)},
  akrun_mapply_match = {mapply(match, v1, L1)},
  akrun_map2 = {purrr::map2_int(L1, v1, ~ .x %in% .y %>% which)},
  CPak = {setNames(rep(1:length(L1), times=lengths(L1)), unlist(L1))[as.character(v1)]},
  zacdav = {sequence(lengths(L1))[match(v1, unlist(L1))]},
  zacdav_which = {sequence(lengths(L1))[which(unlist(L1) %in% v1)]},
  times = 10000
)

Unit: microseconds
               expr     min       lq      mean   median       uq        max neval
       akrun_sapply  18.187  22.7555  27.17026  24.6140  27.8845   2428.194 10000
    akrun_Vectorize  60.119  76.1510  88.82623  83.4445  89.9680   2717.420 10000
       akrun_mapply  19.006  24.2100  29.78381  26.2120  29.9255   2911.252 10000
 akrun_mapply_match  14.136  18.4380  35.45528  20.0275  23.6560 127960.324 10000
         akrun_map2 217.209 264.7350 303.64609 277.5545 298.0455   9204.243 10000
               CPak  15.741  19.7525  27.31918  24.7150  29.0340    235.245 10000
             zacdav   6.649   9.3210  11.30229  10.4240  11.5540   2399.686 10000
       zacdav_which   7.364  10.2395  12.22632  11.2985  12.4515   2492.789 10000

答案 3 :(得分:1)

我们也可以使用

<form action="#">
  <label>Value: <input id="a"/></label>
  <label>Value: <input id="b"/></label>
  <label>Value: <input id="c"/></label>
  <button type="submit">Submit</button>
</form>

或使用

unlist(lapply(L1, function(x) which(x %in% v1)))

#[1] 1 2 4