problemy z dplyr podczas używania group by(wiele zmiennych)
Chcę zacząć używać dplyr zamiast ddply, ale nie mogę zrozumieć, jak to działa (przeczytałem dokumentację).
Na przykład, dlaczego gdy próbuję zmutować () coś nie działa tak jak powinno?
Patrząc na mtcars:
Biblioteka (samochód)
Powiedzmy, że robię dane.rama będąca podsumowaniem mtcars, pogrupowanych według " cyl " i "gear":df1 <- mtcars %.%
group_by(cyl, gear) %.%
summarise(
newvar = sum(wt)
)
Następnie powiedz, że chcę dalej podsumować tę ramkę danych. Z ddply byłoby proste, ale kiedy próbuję zrobić z dplyr, to nie jest tak naprawdę "grupowanie przez": {]}
df2 <- df1 %.%
group_by(cyl) %.%
mutate(
newvar2 = newvar + 5
)
Nadal daje niezgrupowane wyjście:
cyl gear newvar newvar2
1 6 3 6.675 11.675
2 4 4 19.025 24.025
3 6 4 12.375 17.375
4 6 5 2.770 7.770
5 4 3 2.465 7.465
6 8 3 49.249 54.249
7 4 5 3.653 8.653
8 8 5 6.740 11.740
Czy robię coś nie tak ze składnią?
Edit:
Gdybym to zrobił z plyr i ddply:
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
A następnie uzyskać drugie df:
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
Ale to samo podejście, z sum (newvar) + 5 w funkcji summary () nie działa z dplyr...
5 answers
Biorąc odpowiedź Dicoa krok dalej -- jak mówi Hadley "summary złuszcza jedną warstwę grupowania". Odrywa się od odwrotnej kolejności, w jakiej został zastosowany, dzięki czemu można po prostu użyć
mtcars %>%
group_by(cyl, gear) %>%
summarise(newvar = sum(wt)) %>%
summarise(newvar2 = sum(newvar) + 5)
Zwróć uwagę, że to da inną odpowiedź, jeśli użyjesz group_by(gear, cyl)
w drugiej linii.
I aby pierwsza próba zadziałała:
df1 <- mtcars %>%
group_by(cyl, gear) %>%
summarise(newvar = sum(wt))
df2 <- df1 %>%
group_by(cyl) %>%
summarise(newvar2 = sum(newvar)+5)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-28 22:07:40
Miałem podobny problem. Znalazłem, że po prostu odłączenie plyr
rozwiązało to:
detach(package:plyr)
library(dplyr)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 19:29:34
Jeśli przetłumaczysz swój kod plyr
na dplyr
używając summarise
zamiast mutate
, uzyskasz takie same wyniki.
library(plyr)
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
df2
## cyl newvar2
## 1 4 30.143
## 2 6 26.820
## 3 8 60.989
detach(package:plyr)
library(dplyr)
mtcars %.%
group_by(cyl, gear) %.%
summarise(newvar = sum(wt)) %.%
group_by(cyl) %.%
summarise(newvar2 = sum(newvar) + 5)
## cyl newvar2
## 1 4 30.143
## 2 8 60.989
## 3 6 26.820
EDIT
Ponieważ summarise
zrzuca ostatnią grupę (gear
) możesz pominąć drugą group_by
(Zobacz komentarz @hadley poniżej)
library(dplyr)
mtcars %.%
group_by(cyl, gear) %.%
summarise(newvar = sum(wt)) %.%
summarise(newvar2 = sum(newvar) + 5)
## cyl newvar2
## 1 4 30.143
## 2 8 60.989
## 3 6 26.820
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-09 21:28:48
Odłączanie plyr
jest jednym ze sposobów rozwiązania problemu, dzięki czemu można używać funkcji dplyr
zgodnie z potrzebami... ale co, jeśli potrzebujesz innych funkcji z plyr
, aby wykonać inne zadania w kodzie?
(w tym przykładzie mam załadowane biblioteki dplyr
i plyr
)
Załóżmy, że mamy proste dane.ramki i chcemy obliczyć sumę groupwise zmiennej value
, gdy zgrupowane są według różnych poziomów gname
> dx<-data.frame(gname=c(1,1,1,2,2,2,3,3,3), value = c(2,2,2,4,4,4,5,6,7))
> dx
gname value
1 1 2
2 1 2
3 1 2
4 2 4
5 2 4
6 2 4
7 3 5
8 3 6
9 3 7
Ale kiedy spróbujemy użyć tego, co wierzymy, będzie produkować dplyr
suma zespolona, oto co się dzieje:
dx %>% group_by(gname) %>% mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname
gname value mysum
1 1 2 36
2 1 2 36
3 1 2 36
4 2 4 36
5 2 4 36
6 2 4 36
7 3 5 36
8 3 6 36
9 3 7 36
To nie daje nam pożądanej odpowiedzi. Prawdopodobnie z powodu jakiejś interakcji lub przeciążenia funkcji group_by
I or mutate
pomiędzy dplyr
i plyr
. Możemy odłączyć plyr
, ale innym sposobem jest podanie unikalnego wywołania do dplyr
wersji group_by
i mutate
:
dx %>% dplyr::group_by(gname) %>% dplyr::mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname
gname value mysum
1 1 2 6
2 1 2 6
3 1 2 6
4 2 4 12
5 2 4 12
6 2 4 12
7 3 5 18
8 3 6 18
9 3 7 18
Teraz widzimy, że to działa zgodnie z oczekiwaniami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 02:14:41
Dplyr działa tak, jak powinieneś się spodziewać w swoim przykładzie. Mutate, jak go określiłeś, po prostu doda 5 do każdej wartości newvar podczas tworzenia newvar2. To będzie wyglądać tak samo, jeśli grupa lub nie. Jeśli jednak podasz coś, co różni się od grupy, otrzymasz coś innego. Na przykład:
df1 %.%
group_by(cyl) %.%
mutate(
newvar2 = newvar + mean(cyl)
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-09 00:16:31