Bedingt auswählen von Spalten in dplyr, wo bestimmter Anteil der Werte ist NA
Daten
Ich arbeite mit einem Datensatz, die wie die data.frame
darunter generiert:
set.seed(1)
dta <- data.frame(observation = 1:20,
valueA = runif(n = 20),
valueB = runif(n = 20),
valueC = runif(n = 20),
valueD = runif(n = 20))
dta[2:5,3] <- NA
dta[2:10,4] <- NA
dta[7:20,5] <- NA
Spalten NA
Werte mit der letzten Spalte mit mehr als 60% der Beobachtungen NAs
.
> sapply(dta, function(x) {table(is.na(x))})
$observation
FALSE
20
$valueA
FALSE
20
$valueB
FALSE TRUE
16 4
$valueC
FALSE TRUE
11 9
$valueD
FALSE TRUE
6 14
Problem
Möchte ich entfernen können diese Spalte in dplyr
Rohrleitung irgendwie an die select
argument.
Versuche
Dies kann leicht getan werden in base
. Zum Beispiel können Sie Spalten auswählen, die mit weniger als 50% NAs
ich tun kann:
dta[, colSums(is.na(dta)) < nrow(dta) / 2]
produziert:
> head(dta[, colSums(is.na(dta)) < nrow(dta) / 2], 2)
observation valueA valueB valueC
1 1 0.2655087 0.9347052 0.8209463
2 2 0.3721239 NA NA
Aufgabe
Ich bin daran interessiert, erreichen Sie die gleiche Flexibilität in dplyr
pipe-line:
Vectorize(require)(package = c("dplyr", # Data manipulation
"magrittr"), # Reverse pipe
char = TRUE)
dta %<>%
# Some transformations I'm doing on the data
mutate_each(funs(as.numeric)) %>%
# I want my select to take place here
- Sie können
Filter
d.h.Filter(function(x) sum(is.na(x)) < length(x)/2, dta)
- Wie immer vielen Dank für den hilfreichen Beitrag. Ich Frage mich nur, ist das nicht der
filter
sein soll, fallen die Beobachtungen? Ich interessiere mich für das entfernen von Spalten, nicht Zeilen. - Es ist die Entfernung der Spalten, d.h.
Filter
mit KapitalF
- Nun, ich bekam Sie
?Filter != ?filter
🙂 - Noch eine Frage mit Bezug auf das vorschlagen
Filter
Lösung, die ich sehe, dass Sie auf der Durchreise sind diedta
Objekt, auf meine real-Daten ich bin die Anwendung von Transformationen auf die Daten (wiegather
undspread
) so in der Tat das Objekt an dem ich arbeite, entspricht nicht der erstedta
Rahmen. Dies ist der Grund, warum ich fügte hinzu, diesemutate_each(funs(as.numeric)) %>%
in meinem Beispiel zu zeigen, dass ich arbeite auf einer transformiertendta
. Im Effekt, ich habe nicht wirklichdta
weitergeben, nur einen verwandeltdata.frame
nach der Anwendung ein paar Rohre. - Ich habe eine Lösung mit
summarise_each
. Vielleicht hilft es dir.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie dieses vielleicht?
Aktualisiert mit
colMeans
stattcolSums
was bedeutet, dass Sie nicht brauchen, zu dividieren durch die Anzahl der Zeilen nicht mehr.Und, just for the record, in base-R könnten Sie auch
colMeans
:Ich denke, das ist der job:
`
Wir können
extract
ausmagrittr
nachdem Sie einen logischen Vektor mitsummarise_each/unlist
Oder verwenden Sie
Filter
ausbase R
Oder eine etwas kompakte option ist
dta[colMeans(is.na(dta)) < .5]
ist die prägnanteste/vektorisierter/einfach/lesbar ist Lösung, was ist der Punkt in all diesenFilter
oderdplyr/magrittr
Zeug? Ich bin wohl langsam alt.colMeans
,colSums
etc konvertieren die Daten zumatrix
. Es kann nicht sein, dass eine effiziente (kann sein das ich mich Irre). Aber, ich magFilter
denn er fügt einen exotischen touch, um es (genauso wiefilter
in diesem question. Other than, diemagrittr
Zeug ist nur fürdplyr/magritr
fans (meine bescheidene Meinung).is.na
bereits konvertiert von einer matrix.col*
Funktionen funktionieren bereits auf der matrix. So könnten wir tundta[colMeans(sapply(dta, is.na)) < .5]
wenn Sie mögen und es ist immer noch sehr lesbar. Und in diesem verlinkten Frage,filter
ist eigentlich das prägnanteste/vektorisierter/einfache Lösung, eher eine exotische. Aber ich denke, du bist nicht die Adresse hier für meine grange.dplyr
pipeline. Ich rechne damit, dassbase
Lösung beweisen können, in diesem Fall effizienter, aber mein Ehrgeiz war es, sich dieser transformation innerhalb diedplyr
pipe-line. Diese meist motiviert durch eine persönliche Präferenz zu verpflichten, diese transformation entlang der anderen diejenigen, die innerhalb derdplyr
Umfang, die meist Ergebnisse in einem code-Präsentations-und R-Skript, das mir passt besser. Ich bin damit einverstanden, dassbase
beweisen könnte, effizienter aber. Ich auch wie @akrun die Idee der Zugabe der Exotik an der Lösung.dta %>% select(which(colMeans(is.na(.)) < 0.5))
ist das gleiche wie das, was Sie beschreiben, als die meisten vektorisiert/prägnant/... Ansatz außer für einen Aufrufwhich
- sind Sie wirklich besorgt? Für mich ist das durchaus verständlich, die OP ist zu Fragen, speziell für eine "Pipe" zu beantworten, da diese genau Ihren workflow. Es geht nicht um die Suche nach der maximalen Leistung. Und selbst wenn Sie waren, ich denke es ist eher unwahrscheinlich, dass diese Spalte-subsetting-Betrieb wäre eine tatsächliche performance-Engpass in der realen Welt Programme.