将列表中的NaN值替换为零(0)

时间:2013-03-23 00:06:51

标签: r nan

亲爱的,我对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个变量的例子。

4 个答案:

答案 0 :(得分:31)

这是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可以在这种情况下正确处理嵌套列表。

答案 1 :(得分:7)

由于您似乎不介意将数据放在数据框中,因此您也可以执行高度矢量化的操作。但是,这仅在每个列表元素具有相同长度时才有效。我猜你的数据(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

答案 2 :(得分:3)

关注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:从你的帖子看,你想用NaN替换为0. stack(z)的输出,它可以保存到变量然后替换为0然后你可以unstack

注2:此外,由于na.omit删除了NA和NaN,我还假设您的数据不包含NA(来自您上面的数据)。

答案 3 :(得分:1)

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