Wie @DavidArenburg kommentiert, die Art und Weise Ihre Funktion funktioniert, ist nicht, wie dplyr
ausgelegt ist, zu arbeiten. Die .
bedeutet explizit die vollständige Variable (data.frame in diesem Fall) durch die %>%
. Ich habe diesen Hack gelegentlich verwendet, wenn ich etwas mit den vollständigen Daten machen möchte, und etwas in der Gruppe, z.
data %>%
group_by(V1) %>%
mutate(eg = mean(V2)/mean(.$V2))
V1 V2 eg
<fctr> <dbl> <dbl>
1 a 1 0.5714286
2 a 2 0.5714286
3 a 3 0.5714286
4 b 4 1.4285714
5 b 5 1.4285714
6 b 6 1.4285714
gibt daher die beste Lösung mutate
zu bekommen die Gruppierung anzuwenden, ist Spaltenname übergeben (s) statt, zB
func_forColumn = function(data_a) {
value = mean(data_a)
return(value)
}
data %>%
group_by(V1) %>%
mutate(test = func_forColumn(V2))
gibt
V1 V2 test
<fctr> <dbl> <dbl>
1 a 1 2
2 a 2 2
3 a 3 2
4 b 4 5
5 b 5 5
6 b 6 5
Wenn Sie echte Sie müssen in der Lage sein, den vollständigen data.frame zu übergeben (zB arbeiten Sie mit Funktionen, die für ein altes Paradigma geschrieben wurden und können sie aus irgendeinem Grund nicht aktualisieren), Sie könnten entweder split
/lapply
verwenden, wie ich es von Ihnen gewohnt bin , dann nur bind_rows
das Ergebnis, etwa so:
data %>%
split(.$V1) %>%
lapply(function(x){
x %>%
mutate(test = func_a(.))
}) %>%
bind_rows()
die gibt
V1 V2 test
1 a 1 2
2 a 2 2
3 a 3 2
4 b 4 5
5 b 5 5
6 b 6 5
oder können Sie do
verwenden, die etwas komplizierte Gruppierung/Zusammenfassung Ausgänge ermöglicht. Diese ist so konzipiert, mehrspaltigen Rückkehr in data.frames zu ermöglichen, kann aber für Ihr Szenario angepasst werden:
data %>%
group_by(V1) %>%
do(as.data.frame(func_a(.)))
gibt
V1 `func_a(.)`
<fctr> <dbl>
1 a 2
2 b 5
Beachten Sie, dass es nur eine Zeile pro Gruppe zurückgibt. Sie müssten also einen Join (z. B. left_join
) zu den Originaldaten verwenden, wenn Sie eine Zeile pro Originaleintrag benötigen.
Hier ist ein typischeres Beispiel für die Verwendung von do
, die eher mit dem Grund zusammenhängt, warum Ihre Funktionen einen vollständigen data.frame erwarten.
mySummary <- function(x){
as.data.frame(rbind(summary(x)))
}
data %>%
group_by(V1) %>%
do(mySummary(.$V2))
V1 Min. `1st Qu.` Median Mean `3rd Qu.` Max.
<fctr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 a 1 1.5 2 2 2.5 3
2 b 4 4.5 5 5 5.5 6
Wie schon geschrieben gibt, gibt es Funktionen, die wie diese werden nicht angewendet, also ja, dann ist es ein Muss. – MaHo
Sie haben Ihre Funktion falsch geschrieben. Es sollte etwas wie 'func_a = function (x) mean (x)' sein und dann könnte man es mit 'data%>% group_by (V1)%>% muate (test = func_a (V2))' oder wenn du willst nennen Es läuft über alle Spalten 'data%>% group_by (V1)%>% mutate_all (Spaß (func_a))' es sei denn, du willst es über 'V2' laufen lassen, ohne es zu sagen? In diesem Fall müssen Sie wahrscheinlich mit 'LazyVal'-Paket herumspielen. –
Danke David, ich kämpfe immer noch ein bisschen mit der Logik davon, aber es funktioniert. Glücklicherweise werde ich Ihre Antwort als Lösung akzeptieren. – MaHo