Jak uniknąć ostrzeżenia przy wprowadzaniu NA przez przymus

124

Generalnie wolę kodować R, aby nie otrzymywać ostrzeżeń, ale nie wiem, jak uniknąć ostrzeżenia podczas as.numerickonwertowania wektora znaków.

Na przykład:

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

Da mi ostrzeżenie, ponieważ wprowadziło NA przez przymus. Chcę, żeby NA wprowadzane przez przymus - czy istnieje sposób, aby powiedzieć „tak, to jest to, co chcę zrobić”. A może powinienem po prostu żyć z ostrzeżeniem?

A może powinienem używać innej funkcji do tego zadania?

Korone
źródło
8
Zobacz ?suppressWarningsmoże?
A5C1D2H2I1M1N2O1R2T1
4
Jaki jest problem z tym ostrzeżeniem? Ogólnie dostarcza cennych informacji. Wolę bardziej szczegółowe wyjście w konsoli R niż nieprzyjemne niespodzianki.
Roland,
12
@Roland Całkowicie się zgadzam, ale użyteczność ostrzeżeń maleje, jeśli przyzwyczaisz się do ich ignorowania. Dlatego generalnie lubię „radzić sobie” z ostrzeżeniami. W tym przypadku ZAWSZE będę generował ostrzeżenia, a wiele z nich - moje dane przychodzą jako ciągi z „X” reprezentującym NA, więc funkcja robi dokładnie to, czego chcę. Chciałem powiedzieć „Dzięki za poinformowanie mnie, ale w porządku, wiem, co robię”. suppressWarningswydaje się doskonały.
Korone,
6
Wiesz, że read.tableakceptuje argument na.strings?
Roland
Warto je pominąć, jeśli masz już obejście znanego błędu w bibliotece. Tak właśnie tego użyję!
Clem Wang

Odpowiedzi:

142

Zastosowanie suppressWarnings():

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

To pomija ostrzeżenia.

Andrie
źródło
Chociaż jest to preferowana odpowiedź, odpowiedź jangoreckiego poniżej wydaje mi się solidniejsza.
Ian
34

suppressWarnings()zostało już wspomniane. Alternatywą jest ręczne przekonwertowanie problematycznych znaków na NA. Zrób taRifx::destringto właśnie dla twojego konkretnego problemu . W ten sposób, jeśli otrzymasz inne, nieoczekiwane ostrzeżenie z funkcji, nie zostanie ono zniesione.

> 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
źródło
3
Wiem, że jest to stary wątek i destringdziała doskonale na przykładzie op, ale jednym zastrzeżeniem dla każdego, kto zobaczy ten wątek w przyszłości, jest to, że destringdziała inaczej niż as.numericwtedy, gdy ciąg docelowy jest mieszaniną ciągu i liczb: to znaczy destring("x1")daje, 1ale as.numeric("x1")dajeNA
Hong,
26

Ogólnie rzecz biorąc, pomijanie ostrzeżeń nie jest najlepszym rozwiązaniem, ponieważ możesz chcieć otrzymać ostrzeżenie, gdy zostaną dostarczone nieoczekiwane dane wejściowe.
Poniższe rozwiązanie to opakowanie służące do utrzymywania tylko NA podczas konwersji typu danych. Nie wymaga żadnego opakowania.

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
źródło
4
To najlepsza odpowiedź. Używanie suppressWarnings()jest ogólnie złym pomysłem, ponieważ czasami musimy zobaczyć te ostrzeżenia.
keberwein
0

Nieznacznie zmodyfikowałem funkcję jangoreckiego w przypadku, gdy możemy mieć różne wartości, których nie można przekonwertować na liczbę. W mojej funkcji wykonywane jest wyszukiwanie szablonu i jeśli szablon nie zostanie znaleziony, zwracany jest FALSE.! przed gperl oznacza to, że potrzebujemy tych elementów wektora, które nie pasują do szablonu. Reszta jest podobna do as.numfunkcji. Przykład:

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
źródło