将列表中的 NaN 值替换为零 (0)
Posted
技术标签:
【中文标题】将列表中的 NaN 值替换为零 (0)【英文标题】:Replace NaN values in a list with zero (0) 【发布时间】:2013-03-12 23:34:57 【问题描述】:嗨,亲爱的,NaN
有问题。我正在处理一个包含许多变量的大型数据集,它们有NaN
。数据是这样的:
z=list(a=c(1,2,3,NaN,5,8,0,NaN),b=c(NaN,2,3,NaN,5,8,NaN,NaN))
我使用此命令将列表强制为数据框,但我得到了:
z=as.data.frame(z)
> is.list(z)
[1] TRUE
> is.data.frame(z)
[1] TRUE
> replace(z,is.nan(z),0)
Error en is.nan(z) : default method not implemented for type 'list'
我强制 z 到数据框,但这还不够,也许有一个表格可以更改列表中的NaN
。谢谢你的帮助。此数据只是一个示例,我的原始数据有 36000 个观测值和 40 个变量。
【问题讨论】:
【参考方案1】:这是rapply
的完美用例。
> rapply( z, f=function(x) ifelse(is.nan(x),0,x), how="replace" )
$a
[1] 1 2 3 0 5 8 0 0
$b
[1] 0 2 3 0 5 8 0 0
lapply
也可以,但rapply
在这种情况下可以正确处理嵌套列表。
【讨论】:
@ricardosaporta 我应该添加“罕见的用例”:-) @AriB.Friedman 这对我来说不起作用,当更改为“is.null”时。我尝试了 【参考方案2】:按照 OP 的编辑:按照您编辑的标题,应该这样做。
unstack(within(stack(z), values[is.nan(values)] <- 0))
# a b
# 1 1 0
# 2 2 2
# 3 3 3
# 4 0 0
# 5 5 5
# 6 8 8
# 7 0 0
# 8 0 0
如果结果输出的长度相同,unstack
会自动为您提供data.frame
(与第一个示例不同,如下所示)。
旧解决方案(用于连续性)。
试试这个:
unstack(na.omit(stack(z)))
# $a
# [1] 1 2 3 5 8 0
# $b
# [1] 2 3 5 8
注意1:从你的帖子看来你想用0替换NaN。stack(z)
的输出,可以保存到一个变量,然后替换为0,然后你可以unstack
。
注意 2:此外,由于 na.omit 删除了 NA 以及 NaN,我还假设您的数据不包含 NA(来自您上面的数据)。
【讨论】:
【参考方案3】:由于您似乎不介意将数据放在数据框中,因此您也可以做一些高度矢量化的事情。但是,这仅在每个列表元素长度相等时才有效。我猜你的数据 (36000/40 = 900
) 是这样的:
z <- as.data.frame(z)
dim <- dim(z)
y <- unlist(z)
y[ is.nan(y) ] <- 0
x <- matrix( y , dim )
# [,1] [,2]
# [1,] 1 0
# [2,] 2 2
# [3,] 3 3
# [4,] 0 0
# [5,] 5 5
# [6,] 8 8
# [7,] 0 0
# [8,] 0 0
【讨论】:
【参考方案4】:z = do.call(data.table, rapply(z, function(x) ifelse(is.nan(x),0,x), how="replace"))
如果您最初有 data.table 并且想要 1 行替换。
但请记住,之后需要重新定义键:
> key(x1)
[1] "date"
> x1 = do.call(data.table, rapply(x1, function(x) ifelse(is.na(x), 0, x), how="replace"))
> key(x1)
NULL
【讨论】:
以上是关于将列表中的 NaN 值替换为零 (0)的主要内容,如果未能解决你的问题,请参考以下文章