替换 R 中多个列表元素中的 NA



假设我有以下列表:

list(c(1:5,NA,NA),NA,c(NA,6:10))
[[1]]
[1]  1  2  3  4  5 NA NA
[[2]]
[1] NA
[[3]]
[1] NA  6  7  8  9 10

我想用0替换所有NA

[[1]]
[1] 1 2 3 4 5 0 0
[[2]]
[1] 0
[[3]]
[1]  0  6  7  8  9 10

我最初认为is.na会参与其中,但无法让它影响所有列表元素。我从相关问题(从列表列表中删除 NA(中了解到,使用 lapply 将允许我将is.na应用于每个元素,但该帖子演示了如何删除(而不是替换(NA值。

如何替换多个列表元素中的NA值?

我已经尝试了for循环和ifelse方法,但我尝试过的所有方法要么很慢,要么不起作用,要么只是笨拙。必须有一种简单的方法可以使用apply函数来做到这一点......

还有

下面是使用 replace 函数的简单lapply方法:

L1 <-list(c(1:5,NA,NA),NA,c(NA,6:10))
lapply(L1, function(x) replace(x,is.na(x),0))

具有预期的结果:

[[1]]
[1] 1 2 3 4 5 0 0
[[2]]
[1] 0
[[3]]
[1]  0  6  7  8  9 10

有多种方法可以做到这一点:

使用来自咕噜咕噜包的map

lt <- list(c(1:5,NA,NA),NA,c(NA,6:10))
lt %>% 
    map(~replace(., is.na(.), 0))

#output
[[1]]
[1] 1 2 3 4 5 0 0
[[2]]
[1] 0
[[3]]
[1]  0  6  7  8  9 10
kk<- list(c(1:5,NA,NA),NA,c(1,6:10))
lapply(kk, function(i) 
  { p<- which(is.na(i)==TRUE)
    i[p] <- 0
    i
  })

根据格雷戈尔的赞扬编辑

lapply(kk, function(i) {i[is.na(i)] <- 0; i})

我决定对提到的各种lapply方法进行基准测试

lapply(Lt, function(x) replace(x,is.na(x),0)) 
lapply(Lt, function(x) {x[is.na(x)] <- 0; x})
lapply(Lt, function(x) ifelse(is.na(x), 0, x)) 

基准测试代码:

Lt <- lapply(1:10000, function(x)  sample(c(1:10000,rep(NA,1000))) )    ##Sample list
elapsed.time <- data.frame(
    m1 = mean(replicate(25,system.time(lapply(Lt, function(x) replace(x,is.na(x),0)))[3])),
    m2 = mean(replicate(25,system.time(lapply(Lt, function(x) {x[is.na(x)] <- 0; x}))[3])),
    m3 = mean(replicate(25,system.time(lapply(Lt, function(x) ifelse(is.na(x), 0, x)))[3]))
  )

结果:

Function                                          Average Elapsed Time
lapply(Lt, function(x) replace(x,is.na(x),0))     0.8684 
lapply(Lt, function(x) {x[is.na(x)] <- 0; x})     0.8936
lapply(Lt, function(x) ifelse(is.na(x), 0, x))    8.3176

replace方法最快,紧随其后的是[]方法。ifelse方法慢 10 倍。

这将处理任何列表深度和结构:

x <-  eval(parse(text=gsub("NA","0",capture.output(dput(a)))))
# [[1]]
# [1] 1 2 3 4 5 0 0
# 
# [[2]]
# [1] 0
# 
# [[3]]
# [1]  0  6  7  8  9 10

试试这个:

lapply(enlist, function(x) { x[!is.na(x)]})

哪里:

enlist <- list(c(1:5,NA,NA),NA,c(NA,6:10))

这会产生:

[[1]]
[1] 1 2 3 4 5
[[2]]
logical(0)
[[3]]
[1]  6  7  8  9 10

最新更新