Pergunta
Eu tenho um quadro de dados com várias colunas de fatores contendo NaN
é para o qual eu gostaria de converter NA
de (o NaN
parece ser um problema para o uso de objetos de regressão linear para prever novos dados).
> 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"
Solução
Aqui está o problema:Seu vetor está no modo caractere, então é claro que "não é um número".Esse último elemento foi interpretado como a string “NaN”.Usando is.nan
só fará sentido se o vetor for numérico.Se você quiser fazer com que um valor esteja faltando em um vetor de caracteres (para que ele seja tratado corretamente pelas funções de regressão), use (sem aspas), 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
Nem "NA" nem "NaN" estão realmente faltando nos vetores de caracteres.Se por algum motivo houvesse valores em uma variável de fator que fossem "NaN", você poderia simplesmente usar a indexação lógica:
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
Esse último resultado pode ser surpreendente.Existe um nível "NaN" restante, mas nenhum dos elementos é "NaN".Em vez disso, o elemento que era "NaN" agora é um valor real ausente, significado na impressão como .
Outras dicas
Você não pode ter NaN
em um vetor de caracteres, que é o que você tem aqui:
> 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"
Observe como R pensa que isso é uma sequência de caracteres.
Você pode criar NaN
em um vetor numérico:
> 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
Então, é claro, R pode converter NaN
para NA
conforme seu código:
> foo <- as.numeric(tester1)
> foo[is.nan(foo)] <- NA
> foo
[1] 2 2 3 4 2 3 NA
EDITAR:
Gavin Simpson nos comentários me lembra que, na sua situação, existem maneiras muito mais fáceis de converter o que é realmente um "NaN" em um "NA":
tester1 <- gsub("NaN", "NA", tester1)
tester1
# [1] "2" "2" "3" "4" "2" "3" "NA"
Solução:
Para detectar quais elementos do vetor de caracteres são NaN
, você precisa converter o vetor em um vetor numérico:
tester1[is.nan(as.numeric(tester1))] <- "NA"
tester1
[1] "2" "2" "3" "4" "2" "3" "NA"
Explicação:
Existem alguns motivos pelos quais isso não está funcionando como você espera.
Primeiro, embora NaN
significa "Not a Number", tem classe "numeric"
, e só faz sentido dentro de um vetor numérico.
Segundo, quando incluído em um vetor de caracteres, o símbolo NaN
é silenciosamente convertido para a sequência de caracteres "NaN"
.Quando você então testa nan
-ness, a sequência de caracteres retorna FALSE
:
class(NaN)
# [1] "numeric"
c("1", NaN)
# [1] "1" "NaN"
is.nan(c("1", NaN))
# [1] FALSE FALSE