17

嗨亲爱的我有一个问题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

4 回答 4

34

这是一个完美的用例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在这种情况下可以正确处理嵌套列表。

于 2013-03-23T00:08:43.723 回答
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
于 2013-03-23T00:32:58.813 回答
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

unstackdata.frame如果结果输出的长度相等,则会自动为您提供 a (与第一个示例不同,如下所示)。


旧解决方案(用于连续性)。

尝试这个:

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(来自您上面的数据)。

于 2013-03-23T00:09:35.980 回答
1
z = do.call(data.table, rapply(z, function(x) ifelse(is.nan(x),0,x), how="replace"))

如果您最初有 data.table 并且想要 1-line 替换。

但请记住,之后需要重新定义键:

> key(x1)
[1] "date"
> x1 = do.call(data.table, rapply(x1, function(x) ifelse(is.na(x), 0, x), how="replace"))
> key(x1)
NULL
于 2015-01-15T18:18:34.287 回答