I have the following \'list\' in R:
[[1]]
[1] 17336 5246 8597 5246 17878 19701
[[2]]
[1] 19701 37748 18155 5246 8597
[[3]]
[1] 12297 19701 17878 5246 173
One thought is to identify the elements of the list that contain your value. Then subset the list, and remove the required elements of the vector in those list elements
This can be done in a single lapply
statement using if{}else{}
lst <- list(c(1,2,3),
c(2,3,4),
c(3,4,5),
c(4,5,6))
lst <- lapply(lst, function(x){
if(any(x %in% 5)){
x[-c(1:which(x == 5))]
}else{
x
}
})
# lst
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 2 3 4
#
# [[3]]
# numeric(0)
#
# [[4]]
# [1] 6
It appears the for
-loop performs better
library(microbenchmark)
microbenchmark(
Symbolix = {
lapply(x, function(x){
if(any(x %in% 5L)){
x[-c(1L:which(x == 5L))]
}else{
x
}
})
},
bgoldst = {
v <- 5L;
for (li in seq_along(x))
if (!is.na(vi <- match(v,x[[li]])))
x[[li]] <- x[[li]][-1:-vi];
},
thelatemail = {
lapply(lst, function(x) tail(x, -Position(isTRUE, x==5, nomatch=-Inf)) )
},
Jota = {for (li in seq_along(x)) if (any(x[[li]] == v, na.rm = TRUE)) x[[li]] <- x[[li]][-1:-match(v,x[[li]])];}
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Symbolix 55.082 62.1750 70.93372 67.8025 73.4365 159.070 100
# bgoldst 27.186 30.9555 35.67991 32.0970 39.3185 100.706 100
# thelatemail 59.665 65.9235 76.64469 72.1920 78.4580 195.755 100
# Jota 11.797 13.8760 17.74330 14.9370 21.7510 43.929 100