简体   繁体   中英

How can I replace a specific value (e.g. -10000) with NA within a big list?

This works for the first list element:

values[[1]][values[[1]]==-10000] <-NA

As I do not want to loop over my thousand list elements I'm looking for a command which does the same for the whole list like:

 values[values==-10000] <-NA

But this does not work for the type list:

Error in values[values == -10000] <- NA : (list) object cannot be coerced to type 'double'

Try using lapply :

lst <- list(v1=-10000, v2=500, v3=c(1,2))
lapply(lst, function(x) ifelse(x==-10000, NA, x))

$v1
 [1] NA

$v2
[1] 500

$v3
[1] 1 2

This approach is also robust even if some of the list elements are not numbers, but are other things, such as vectors. In that case, a vector would not match to your target value, and would not be changed.

As you mention "big list" I provide a second option that uses replace instead which is a bit quicker compared to ifelse .

Thanks to @TimBiegeleisen for the data

lst <- list(v1=-10000, v2=500, v3=c(1,2))
lapply(lst, function(x) replace(x, x == -10000, NA))
#$v1
#[1] NA
#
#$v2
#[1] 500
#
#$v3
#[1] 1 2

benchmark

l <- rep(lst, 100000)
library(microbenchmark)
benchmark <- microbenchmark(
  tim = lapply(l, function(x) ifelse(x==-10000, NA, x)),
  markus = lapply(l, function(x) replace(x, x==-10000, NA))
)

autoplot(benchmark) 

在此处输入图片说明

benchmark
#Unit: milliseconds
#   expr      min        lq      mean    median        uq      max neval cld
#    tim 931.5551 1003.0364 1054.7647 1018.7956 1082.3210 2536.373   100   b
# markus 432.3821  473.9881  500.4833  482.5838  515.9907 1023.392   100  a 

Using na_if with map

library(tidyverse)
map(lst, na_if, y = -10000)
#$v1
#[1] NA

#$v2
#[1] 500

#$v3
#[1] 1 2

data

lst <- list(v1=-10000, v2=500, v3=c(1,2))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM