R не может преобразовать NaN в NA

У меня есть кадр данных с несколькими столбцами факторов, содержащими NaN, которые я хотел бы преобразовать в NA (NaN кажется проблемой для использования объектов линейной регрессии для прогнозирования новых данных).

> tester1 <- c("2", "2", "3", "4", "2", "3", NaN)
> tester1 
[1] "2"   "2"   "3"   "4"   "2"   "3"   "NaN"
> tester1[is.nan(tester1)] = NA
> tester1 
[1] "2"   "2"   "3"   "4"   "2"   "3"   "NaN"
> tester1[is.nan(tester1)] = "NA"
> tester1 
[1] "2"   "2"   "3"   "4"   "2"   "3"   "NaN"

r nan na
person screechOwl    schedule 27.02.2012    source источник
comment
возможно, вы захотите взглянуть на setattr из пакета data.table. Также проверьте ответ Мэтью Доула на мой вопрос ранее сегодня: stackoverflow.com/questions/9463980/   -  person Matt Bannert    schedule 28.02.2012
comment
Пример не имеет смысла: как вы предлагаете использовать символьные данные в линейной регрессии?   -  person Gavin Simpson    schedule 28.02.2012
comment
Это фактор. В последний раз я проверял, что lm() может иметь дело с факторами. Я должен был использовать factor() вокруг примера.   -  person screechOwl    schedule 28.02.2012


Ответы (3)


Вот в чем проблема: ваш вектор является символом в режиме, поэтому, конечно, это «не число». Этот последний элемент был интерпретирован как строка «NaN». Использование is.nan имеет смысл только в том случае, если вектор является числовым. Если вы хотите, чтобы значение отсутствовало в векторе символов (чтобы оно правильно обрабатывалось функциями регрессии), затем используйте (без кавычек) NA_character_.

> tester1 <- c("2", "2", "3", "4", "2", "3", NA_character_)
>  tester1
[1] "2" "2" "3" "4" "2" "3" NA 
>  is.na(tester1)
[1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

Ни "NA", ни "NaN" на самом деле отсутствуют в символьных векторах. Если бы по какой-то причине в переменной фактора были значения «NaN», вы могли бы просто использовать логическое индексирование:

tester1[tester1 == "NaN"] = "NA"  
# but that would not really be a missing value either 
# and it might screw up a factor variable anyway.

tester1[tester1=="NaN"] <- "NA"
Warning message:
In `[<-.factor`(`*tmp*`, tester1 == "NaN", value = "NA") :
invalid factor level, NAs generated
##########
tester1 <- factor(c("2", "2", "3", "4", "2", "3", NaN))

> tester1[tester1 =="NaN"] <- NA_character_
> tester1
[1] 2    2    3    4    2    3    <NA>
Levels: 2 3 4 NaN

Последний результат может удивить. Остался уровень "NaN", но ни один из элементов не является "NaN". Вместо этого элемент, который был «NaN», теперь является реальным отсутствующим значением, обозначенным в печати как .

person IRTFM    schedule 27.02.2012

Вы не можете иметь NaN в векторе символов, что у вас есть здесь:

> tester1 <- c("2", "2", "3", "4", "2", "3", NaN)
> is.nan(tester1)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> tester1
[1] "2"   "2"   "3"   "4"   "2"   "3"   "NaN"

Обратите внимание, как R считает, что это строка символов.

Вы можете создать NaN в числовом векторе:

> tester1 <- c("2", "2", "3", "4", "2", "3", NaN)
> as.numeric(tester1)
[1]   2   2   3   4   2   3 NaN
> is.nan(as.numeric(tester1))
[1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

Затем, конечно, R может преобразовать NaN в NA в соответствии с вашим кодом:

> foo <- as.numeric(tester1)
> foo[is.nan(foo)] <- NA
> foo
[1]  2  2  3  4  2  3 NA
person Gavin Simpson    schedule 27.02.2012

ИЗМЕНИТЬ:

Гэвин Симпсон в комментариях напоминает мне, что в вашей ситуации есть гораздо более простые способы преобразовать то, что на самом деле является «NaN», в «NA»:

tester1 <- gsub("NaN", "NA", tester1)
tester1
# [1] "2"  "2"  "3"  "4"  "2"  "3"  "NA"

Решение:

Чтобы определить, какие элементы вектора символов равны NaN, вам нужно преобразовать вектор в числовой вектор:

tester1[is.nan(as.numeric(tester1))] <- "NA"
tester1
[1] "2"  "2"  "3"  "4"  "2"  "3"  "NA"

Пояснение:

Есть несколько причин, по которым это не работает так, как вы ожидаете.

Во-первых, хотя NaN означает «Не число», он имеет класс "numeric" и имеет смысл только внутри числового вектора.

Во-вторых, когда он включен в вектор символов, символ NaN молча преобразуется в строку символов "NaN". Когда вы затем проверяете его на nan-ность, строка символов возвращает FALSE:

class(NaN)
# [1] "numeric"
c("1", NaN)
# [1] "1"   "NaN"
is.nan(c("1", NaN))
# [1] FALSE FALSE
person Josh O'Brien    schedule 27.02.2012
comment
??? Это преобразование строки NaN в NA очень окольным путем. Конечно, это не то, чего хотел ОП, даже если они пытались использовать NA как NA в одном из своих примеров. - person Gavin Simpson; 28.02.2012
comment
@ГэвинСимпсон -- хорошо. Исправлено сейчас. Спасибо за похлопывание по плечу, напомнившее мне вытащить голову из... сорняков! - person Josh O'Brien; 28.02.2012
comment
Я все еще думаю, что вы слишком много думаете о том, чего хочет ОП. Он хочет, чтобы NaN было преобразовано в NA не строковые версии, а настоящие R-версии, указывающие Not A Number и отсутствие соответственно. Игнорируйте "NA" в одном из примеров OP - это отвлекающий маневр, я полагаю, они думали, что цитирование NA может работать как NA в векторе символов или что-то в этом роде. - person Gavin Simpson; 28.02.2012
comment
@GavinSimpson - я знаю, что вы имеете в виду, но ОП также цитирует все целые числа в примерах векторов, так что там больше 25 отвлекающих маневров, если вы правы. (Хотя ссылка на NaN, создающая проблемы в линейной регрессии, теперь заставляет меня думать, что вы, вероятно, правы). - person Josh O'Brien; 28.02.2012
comment
Ух ты. Мой первый в истории отрицательный голос, предположительно, за ответ на вопрос, который на самом деле задал ОП, а не на то, что они, возможно, хотели задать !? Ну что ж. - person Josh O'Brien; 28.02.2012
comment
Вы не ответили на вопрос, который задал ОП. @DWin сделал это. Они хотят преобразовать NaN в NA. Это почти не имеет ничего общего со строками (кроме того, что источник is.nan() не соответствует "NaN". В tester1 OP нет NaN (есть "NaN"). Первая строка Q довольно явная - без кавычек там - даже если пример кода, показывающий, что сделал OP, включает "NA" Конечно, это один из самых запутанных вопросов, которые я когда-либо видел; я понятия не имею, как что-то отдаленно похожее на tester1 используется в регрессии. - person Gavin Simpson; 28.02.2012
comment
Что ж, струны в конечном итоге имели к этому большое отношение. В конце концов, ОП уже знал, как изменить NaNs на NAs (см. Строку 4 вопроса!), Но не понимал, что происходит молчаливое преобразование NaN в "NaN". Я думаю, мы можем, по крайней мере, согласиться с тем, что вопрос сбивает с толку. Ваше здоровье. - person Josh O'Brien; 28.02.2012