Como evitar avisos ao introduzir NAs por coerção

124

Geralmente, prefiro codificar R para não receber avisos, mas não sei como evitar um aviso as.numericao converter um vetor de caractere.

Por exemplo:

x <- as.numeric(c("1", "2", "X"))

Me dará um aviso porque introduziu NAs por coerção. Eu quero NAs introduzidas por coerção - existe uma maneira de dizer "sim, é isso que eu quero fazer". Ou devo apenas viver com o aviso?

Ou devo usar uma função diferente para esta tarefa?

Korone
fonte
8
?suppressWarningstalvez?
A5C1D2H2I1M1N2O1R2T1
4
Qual é o problema com este aviso? Geralmente, fornece informações valiosas. Prefiro uma saída mais detalhada no console do R a surpresas desagradáveis.
Roland
12
@Roland Eu concordo totalmente, mas a utilidade dos avisos diminui se você se acostumar a ignorá-los. É por isso que geralmente gosto de "atacar" os avisos. Nesse caso, eu sempre gerarei avisos, e muitos deles - meus dados estão chegando como cadeias com "X" representando NA e, portanto, a função está fazendo exatamente o que eu quero que faça. Eu queria dizer "Obrigado por me avisar, mas tudo bem, eu sei o que estou fazendo". suppressWarningsparece perfeito.
21413 Korone
6
Você sabe que read.tableaceita um argumento na.strings?
Roland
É útil suprimi-los se você já tiver uma solução alternativa para um bug conhecido em uma biblioteca. É assim que eu vou usar isso!
Clem Wang

Respostas:

142

Use suppressWarnings():

suppressWarnings(as.numeric(c("1", "2", "X")))
[1]  1  2 NA

Isso suprime avisos.

Andrie
fonte
Embora essa seja a resposta preferida, a resposta de jangorecki abaixo parece, para mim, mais sólida.
Ian
34

suppressWarnings()já foi mencionado. Uma alternativa é converter manualmente os caracteres problemáticos para NA primeiro. Para o seu problema específico, taRifx::destringfaz exatamente isso. Dessa forma, se você receber outro aviso inesperado de sua função, ele não será suprimido.

> library(taRifx)
> x <- as.numeric(c("1", "2", "X"))
Warning message:
NAs introduced by coercion 
> y <- destring(c("1", "2", "X"))
> y
[1]  1  2 NA
> x
[1]  1  2 NA
Ari B. Friedman
fonte
2
Eu sei que esse é um thread antigo e destringfunciona perfeitamente para o exemplo do op, mas uma ressalva para quem vê esse thread no futuro é que destringfunciona de maneira diferente de as.numericquando a string de destino é uma mistura de string e numérica: ou seja, destring("x1")1mas as.numeric("x1")NA
Hong
26

Em geral, suprimir avisos não é a melhor solução, pois você pode ser avisado quando alguma entrada inesperada for fornecida.
A solução abaixo é um invólucro para manter apenas NA durante a conversão do tipo de dados. Não requer nenhum pacote.

as.num = function(x, na.strings = "NA") {
    stopifnot(is.character(x))
    na = x %in% na.strings
    x[na] = 0
    x = as.numeric(x)
    x[na] = NA_real_
    x
}
as.num(c("1", "2", "X"), na.strings="X")
#[1]  1  2 NA
jangorecki
fonte
4
Esta é a melhor resposta. Usar suppressWarnings()geralmente é uma má ideia, porque às vezes precisamos ver esses avisos.
Keberwein
0

Modifiquei levemente a função jangorecki para o caso em que podemos ter uma variedade de valores que não podem ser convertidos em um número. Na minha função, uma pesquisa de modelo é realizada e, se o modelo não for encontrado, FALSE será retornado.! antes do gperl, significa que precisamos desses elementos vetoriais que não correspondem ao modelo. O resto é semelhante à as.numfunção. Exemplo:

as.num.pattern <- function(x, pattern){
  stopifnot(is.character(x))
  na = !grepl(pattern, x)
  x[na] = -Inf
  x = as.numeric(x)
  x[na] = NA_real_
  x
}

as.num.pattern(c('1', '2', '3.43', 'char1', 'test2', 'other3', '23/40', '23, 54 cm.'))

[1] 1.00 2.00 3.43   NA   NA   NA   NA   NA
Vladislav Shufinskiy
fonte