2015-10-02 3 views
10

Wenn ich filter aus dem dplyr-Paket verwende, um eine Ebene einer Faktorvariablen zu löschen, fallen auch die filter Werte. Hier ein Beispiel:Warum lässt der dplyr-Filter NA-Werte von einer Faktorvariablen fallen?

library(dplyr) 
set.seed(919) 
(dat <- data.frame(var1 = factor(sample(c(1:3, NA), size = 10, replace = T)))) 
# var1 
# 1 <NA> 
# 2  3 
# 3  3 
# 4  1 
# 5  1 
# 6 <NA> 
# 7  2 
# 8  2 
# 9 <NA> 
# 10 1 

filter(dat, var1 != 1) 
# var1 
# 1 3 
# 2 3 
# 3 2 
# 4 2 

Dies gilt nicht ideal erscheinen - ich wollte nur Zeilen fallen, wo var1 == 1.

Es sieht so aus, als ob jeder comparison with NA returns NA, der filter dann fällt. So liefert zum Beispiel filter(dat, !(var1 %in% 1)) die korrekten Ergebnisse. Aber gibt es eine Möglichkeit zu sagen, filter nicht die NA Werte fallen zu lassen?

+2

@akrun Aus irgendeinem Grund habe ich diese Benachrichtigung nicht erhalten: P. Nun, ich dachte, dass das OP schon davon weiß, wie er 'filter (dat,! (Var1% in% 1))' erwähnt hat, was ähnlich ist, aber ich denke, das wäre der einzige Weg, es mit 'dplyr :: Filter ". – LyzandeR

+1

Ich glaube nicht, dass es eine Möglichkeit gibt, explizit zu sagen, dass "Filter" NA-Werte nicht fallen lassen soll, aber im Allgemeinen können logische NA-Anfragen intuitiv mit dem Basis-Operator "% in%" und seiner Negation behandelt werden % ni% <- Negieren ('% in%') '. Sie können also 'filter (dat, var1% ni% 1)' verwenden, das funktioniert. Siehe http://StackOverflow.com/a/11303276/4269699 und http://StackOverflow.com/a/27015823/4269699 – wjchulme

+1

Ja, ich wusste sowohl über diesen Ansatz als auch über den Ansatz, den @LyzandeR für eine Antwort verwendet hat . Es sieht so aus, als hätte der Filter keine explizite Option für "keep NA", so dass diese Problemumgehungen in Ordnung sind. Danke für Ihre Hilfe. –

Antwort

14

könnten Sie verwenden:

filter(dat, var1 != 1 | is.na(var1)) 
    var1 
1 <NA> 
2 3 
3 3 
4 <NA> 
5 2 
6 2 
7 <NA> 

Und es wird nicht.

auch nur für die Fertigstellung, fallen NAs ist das beabsichtigte Verhalten von filter, wie Sie aus der folgenden sehen:

test_that("filter discards NA", { 
    temp <- data.frame(
    i = 1:5, 
    x = c(NA, 1L, 1L, 0L, 0L) 
) 
    res <- filter(temp, x == 1) 
    expect_equal(nrow(res), 2L) 
}) 

Dieser Test oben aus den Tests für filter von github genommen wurde.

+2

Wagst du ein bisschen in mein Meinung basierendes Territorium, hast du eine Idee, warum dies der gewählte Ansatz ist? Dieses Verhalten war unerwartet für mich (ich wurde heute davon gebissen). – Heisenberg

+1

@Heisenberg Ich gehe davon aus, dass laut Hadley die meisten Leute beim Filtern keine NAs wollen. Aber das ist eine Frage für den Entwickler/Betreuer, d.h. Hadley. – LyzandeR

Verwandte Themen