Замените значения NaN в списке с нулем (0)

Привет, дорогая, у меня проблема с 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 правильно справляется с вложенными списками в этой ситуации.

Ответ 2

Как вы, кажется, не возражаете, что ваши данные в фреймворке данных, вы также можете сделать что-то очень векторизованное. Однако это будет работать, только если каждый элемент списка имеет равную длину. Я предполагаю в ваших данных (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

Ответ 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 (из ваших данных выше).

Ответ 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