ich eine data.frame wie diese haben (die reale Datensatz hat viel mehr Zeilen und Spalten)Performing dplyr auf Teilmenge von Spalten mutieren
set.seed(15)
dd <- data.frame(id=letters[1:4], matrix(runif(5*4), nrow=4))
# id X1 X2 X3 X4 X5
# 1 a 0.6021140 0.3670719 0.6872308 0.5090904 0.4474437
# 2 b 0.1950439 0.9888592 0.8314290 0.7066286 0.9646670
# 3 c 0.9664587 0.8151934 0.1046694 0.8623137 0.1411871
# 4 d 0.6509055 0.2539684 0.6461509 0.8417851 0.7767125
Ich mag wäre in der Lage sein, eine dplyr Erklärung zu schreiben, in dem Ich kann eine Teilmenge von Spalten auswählen und mutieren. (Ich versuche etwas Ähnliches wie die Verwendung von .SDcols in data.table).
Für ein vereinfachtes Beispiel, hier ist die Funktion Ich möchte in der Lage sein zu schreiben, Spalten für die Summen und Mittel der geraden "X" Spalten hinzufügen, während alle anderen Spalten erhalten. Die gewünschte Ausgabe unter Verwendung der Basis R ist
(cols<-paste0("X", c(2,4)))
# [1] "X2" "X4"
cbind(dd,evensum=rowSums(dd[,cols]),evenmean=rowMeans(dd[,cols]))
# id X1 X2 X3 X4 X5 evensum evenmean
# 1 a 0.6021140 0.3670719 0.6872308 0.5090904 0.4474437 0.8761623 0.4380811
# 2 b 0.1950439 0.9888592 0.8314290 0.7066286 0.9646670 1.6954878 0.8477439
# 3 c 0.9664587 0.8151934 0.1046694 0.8623137 0.1411871 1.6775071 0.8387535
# 4 d 0.6509055 0.2539684 0.6461509 0.8417851 0.7767125 1.0957535 0.5478768
aber ich wollte eine dplyr-ähnliche Kette verwenden, um das Gleiche zu tun. Im allgemeinen Fall würde ich gerne eine der select()
Hilfsfunktionen wie starts_with
, ends_with
, usw. und jede Funktion verwenden können. Hier ist, was habe ich versucht,
library(dplyr)
partial_mutate1 <- function(x, colspec, ...) {
select_(x, .dots=list(lazyeval::lazy(colspec))) %>%
transmute_(.dots=lazyeval::lazy_dots(...)) %>%
cbind(x,.)
}
dd %>% partial_mutate1(num_range("X", c(2,4)),
evensum=rowSums(.), evenmean=rowMeans(.))
jedoch Dies wirft einen Fehler, der
Error in rowSums(.) : 'x' must be numeric
sagt Welche zu sein scheint, weil .
auf die gesamte date.frame zu beziehen scheint eher als die ausgewählte Teilmenge. (gleicher Fehler wie rowSums(dd)
). Beachten Sie jedoch, dass dies die gewünschte Ausgabe erzeugt
partial_mutate2 <- function(x, colspec) {
select_(x, .dots=list(lazyeval::lazy(colspec))) %>%
transmute(evensum=rowSums(.), evenmean=rowMeans(.)) %>%
cbind(x,.)
}
dd %>% partial_mutate2(seq(2,ncol(dd),2))
Ich vermute, das ist eine Art von Umweltproblem? Irgendwelche Vorschläge, wie Sie die Argumente an übergeben, so dass die .
Werte aus dem Datensatz "select() - ed" korrekt übernimmt?
Eine hässliche Art und Weise wäre: 'dd%>% wählen (X2, X4)%>% mutieren (evensum = rowSums(), evenmean = rowMeans()..)%>% wählen (- X2, -X4)%>% cbind (., Dd) ' –
Ich vermute das Problem ist, dass der Versuch, die SE ist messing mit '%>%'. Mit anderen Worten, mit 'rowMeans (.)', Das in '.dots' eingeschlossen ist, kann '%>%' nicht wissen, dass es die Daten dort auch ersetzen sollte. Dies ist nur eine Vermutung. – BrodieG
Ich denke, du hast Recht @ BrodieG.Nach ein bisschen mehr Graben ist das eher ein magrtrit Problem als ein dplyr Problem. Zum Beispiel: 'muate (dd [, - 1], Summen = rowSums (.))' Funktioniert nicht ("object '.' Not found"). Das '.' Symbol ist also nicht speziell für' dplyr'. Der Versuch, eine Funktion über mehrere Spalten hinweg zu verwenden, scheint die falsche Idee zu sein. Ich denke, ich sollte die Daten zuerst in ein "ordentliches" Format umformen. – MrFlick