Replace NaN values in a list with zero (0)

。_饼干妹妹 提交于 2019-12-28 13:47:26

问题


Hi dear I have a problem with NaN. I am working with a large dataset with many variables and they have NaN. The data is like this:

z=list(a=c(1,2,3,NaN,5,8,0,NaN),b=c(NaN,2,3,NaN,5,8,NaN,NaN))

I used this commands to force the list to data frame but I got this:

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'

I forced z to data frame but it wasn't enough, maybe there is a form to change NaN in list. Thanks for your help. This data is only an example my original data has 36000 observations and 40 variables.


回答1:


This is a perfect use case for 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 would work too, but rapply deals properly with nested lists in this situation.




回答2:


As you don't seem to mind having your data in a dataframe, you can do something highly vectorised too. However, this will only work if each list element is of equal length. I am guessing in your data (36000/40 = 900) that this is the case:

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



回答3:


Following OP's edit: Following your edited title, this should do it.

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 automatically gives you a data.frame if the resulting output is of equal length (unlike the first example, shown below).


Old solution (for continuity).

Try this:

unstack(na.omit(stack(z)))
# $a
# [1] 1 2 3 5 8 0

# $b
# [1] 2 3 5 8

Note 1: It seems from your post that you want to replace NaN with 0. The output of stack(z), it can be saved to a variable and then replaced to 0 and then you can unstack.

Note 2: Also, since na.omit removes NA as well as NaN, I also assume that your data contains no NA (from your data above).




回答4:


z = do.call(data.table, rapply(z, function(x) ifelse(is.nan(x),0,x), how="replace"))

If you initially have data.table and want to 1-line the replacement.

But keep in mind that keys are need to be redefined after that:

> key(x1)
[1] "date"
> x1 = do.call(data.table, rapply(x1, function(x) ifelse(is.na(x), 0, x), how="replace"))
> key(x1)
NULL


来源:https://stackoverflow.com/questions/15581743/replace-nan-values-in-a-list-with-zero-0

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!