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