Entfernen Sie NA-Werte aus einem Vektor

191

Ich habe einen riesigen Vektor, der einige NAWerte hat, und ich versuche, den Maximalwert in diesem Vektor zu finden (der Vektor besteht aus allen Zahlen), aber ich kann dies aufgrund der NAWerte nicht tun .

Wie kann ich die NAWerte entfernen , um das Maximum zu berechnen?

CodeGuy
quelle

Antworten:

264

Wenn ?maxSie es versuchen , werden Sie feststellen, dass es tatsächlich ein na.rm =Argument gibt, das standardmäßig auf gesetzt ist FALSE. (Das ist der gemeinsame Standard für viele andere R - Funktionen, einschließlich sum(), mean()etc.)

Die Einstellung na.rm=TRUEmacht genau das, wonach Sie fragen:

d <- c(1, 100, NA, 10)
max(d, na.rm=TRUE)

Wenn Sie alle NAs entfernen möchten , verwenden Sie stattdessen diese Redewendung:

d <- d[!is.na(d)]

Eine letzte Anmerkung: Weitere Funktionen (zB table(), lm()und sort()) haben NA-related Argumente , die unterschiedliche Namen verwenden (und bieten verschiedene Möglichkeiten). Wenn NASie also Probleme bei einem Funktionsaufruf haben, sollten Sie nach einer integrierten Lösung unter den Argumenten der Funktion suchen. Ich habe festgestellt, dass es normalerweise schon einen gibt.

Josh O'Brien
quelle
Das ist eine sehr schlechte Idee. Es schlägt fehl und gibt -Inffür eine daller NAs.
user3932000
@ user3932000 Um anderen klar zu sein, geht es bei Ihrer Beschwerde wirklich darum, wie sich die Basis-R-Funktion max()verhält (wie zum Beispiel, wenn Sie dies tun max(c(NA, NA)). Persönlich halte ich sein Verhalten für vernünftig; Ich gehe davon aus, dass es so konstruiert wurde, dass Sie das erwartete Ergebnis erhalten, wenn Sie Dinge tun wiea <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien
@ user3932000 Etwas tangential, eine der vielen Stärken des R als Datenanalyseplattform ist die anspruchsvolle Umgang mit fehlenden Daten, das Ergebnis von viel seiner Autoren sorgfältiger Überlegung auf dem Teil. (Wenn Sie sich für das Thema interessieren, finden Sie hier eine gute Diskussion einiger der damit verbundenen Probleme aus der Sicht von Programmierern, die R-ähnliche NAHandhabungsfunktionen in Pythons ausgezeichnetes NumPy- Paket integriert haben.)
Josh O'Brien
@ user3932000: Ist diese Antwort wirklich schlecht? Was würden Sie als Maximum der Nullmenge betrachten?
Cliff AB
@CliffAB Es hat kein Maximum. Sie können das Maximum -∞ (und das Min + + ∞) zuweisen, aber das ist nicht immer erwünscht oder intuitiv. Wenn Sie alle NAs aus einem Vektor von NAs entfernen , erwarten Sie einen leeren Vektor, nicht -∞.
user3932000
94

Die na.omitFunktion wird von vielen Regressionsroutinen intern verwendet:

vec <- 1:1000
vec[runif(200, 1, 1000)] <- NA
max(vec)
#[1] NA
max( na.omit(vec) )
#[1] 1000
IRTFM
quelle
20

?maxzeigt Ihnen, dass es einen zusätzlichen Parameter gibt na.rm, den Sie einstellen können TRUE.

Abgesehen davon, wenn Sie das s wirklich entfernen möchten NA, verwenden Sie einfach etwas wie:

myvec[!is.na(myvec)]
Nick Sabbe
quelle
3
Ich denke das ist am besten. na.rm und na.omit fügen der Ausgabe ziemlich viel Müll hinzu.
MadmanLee
Außer na.omithat auch eine Datenrahmenmethode, ist also allgemeiner.
IRTFM
15

Sie können anrufen max(vector, na.rm = TRUE). Im Allgemeinen können Sie die na.omit()Funktion verwenden.

Michael Hoffman
quelle
14

Nur für den Fall, dass jemand, der neu bei R ist, eine vereinfachte Antwort auf die ursprüngliche Frage wünscht

Wie kann ich NA-Werte aus einem Vektor entfernen?

Hier ist es:

Angenommen, Sie haben einen Vektor foowie folgt:

foo = c(1:10, NA, 20:30)

Laufen length(foo)gibt 22.

nona_foo = foo[!is.na(foo)]

length(nona_foo) ist 21, weil die NA-Werte entfernt wurden.

Denken Sie daran, dass is.na(foo)eine boolesche Matrix zurückgegeben wird. Wenn Sie also foomit dem Gegenteil dieses Werts indizieren , erhalten Sie alle Elemente, die nicht NA sind.

Scott C Wilson
quelle
13

Verwendung discardvon purrr (funktioniert mit Listen und Vektoren).

discard(v, is.na) 

Der Vorteil ist, dass es einfach ist, Rohre zu verwenden. Alternativ können Sie die integrierte Teilmengenfunktion verwenden [:

v %>% discard(is.na)
v %>% `[`(!is.na(.))

Beachten Sie, dass na.omitdies bei Listen nicht funktioniert:

> x <- list(a=1, b=2, c=NA)
> na.omit(x)
$a
[1] 1

$b
[1] 2

$c
[1] NA
qwr
quelle
1

Ich habe einen schnellen Benchmark durchgeführt, bei dem die beiden baseAnsätze verglichen wurden, und es stellte sich heraus, dass dies x[!is.na(x)]schneller ist als na.omit. Der Benutzer qwrschlug vor, dass ich es purrr::dicardauch versuche - dies stellte sich als massiv langsamer heraus (obwohl ich gerne Kommentare zu meiner Implementierung und meinem Test entgegennehme!)

microbenchmark::microbenchmark(
  purrr::map(airquality,function(x) {x[!is.na(x)]}), 
  purrr::map(airquality,na.omit),
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)),
  times = 1e6)

Unit: microseconds
                                                     expr    min     lq      mean median      uq       max neval cld
 purrr::map(airquality, function(x) {     x[!is.na(x)] })   66.8   75.9  130.5643   86.2  131.80  541125.5 1e+06 a  
                          purrr::map(airquality, na.omit)   95.7  107.4  185.5108  129.3  190.50  534795.5 1e+06  b 
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)) 3391.7 3648.6 5615.8965 4079.7 6486.45 1121975.4 1e+06   c

Als Referenz ist hier der ursprüngliche Test von x[!is.na(x)]vs na.omit:

microbenchmark::microbenchmark(
    purrr::map(airquality,function(x) {x[!is.na(x)]}), 
    purrr::map(airquality,na.omit), 
    times = 1000000)


Unit: microseconds
                                              expr  min   lq      mean median    uq      max neval cld
 map(airquality, function(x) {     x[!is.na(x)] }) 53.0 56.6  86.48231   58.1  64.8 414195.2 1e+06  a 
                          map(airquality, na.omit) 85.3 90.4 134.49964   92.5 104.9 348352.8 1e+06   b
jsavn
quelle
Sie sollten versuchenpurrr:discard
qwr