替换 R 中多个列表元素中的 NA
Replace NAs in multiple list elements in R
假设我有以下列表:
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
我想将所有 NA
替换为 0
:
[[1]]
[1] 1 2 3 4 5 0 0
[[2]]
[1] 0
[[3]]
[1] 0 6 7 8 9 10
我原本以为 is.na
会涉及,但无法影响所有列表元素。我从相关问题 (Remove NA from list of lists) 中了解到,使用 lapply
将允许我将 is.na
应用于每个元素,但是 post 演示了如何删除(不是 替换) 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
有多种方法可以做到这一点:
使用来自 purrrr 包的 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
})
根据 Gregor 的评论进行编辑
lapply(kk, function(i) {i[is.na(i)] <- 0; i})
试试这个:
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
我决定对提到的各种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
假设我有以下列表:
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
我想将所有 NA
替换为 0
:
[[1]]
[1] 1 2 3 4 5 0 0
[[2]]
[1] 0
[[3]]
[1] 0 6 7 8 9 10
我原本以为 is.na
会涉及,但无法影响所有列表元素。我从相关问题 (Remove NA from list of lists) 中了解到,使用 lapply
将允许我将 is.na
应用于每个元素,但是 post 演示了如何删除(不是 替换) 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
有多种方法可以做到这一点:
使用来自 purrrr 包的 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
})
根据 Gregor 的评论进行编辑
lapply(kk, function(i) {i[is.na(i)] <- 0; i})
试试这个:
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
我决定对提到的各种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