我有一个矢量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)。
有没有办法在不使用循环或应用的情况下执行此操作(在计算上与使用循环相同?)我必须为非常长的向量执行此操作。
答案 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