Względne częstotliwości / proporcje z dplyr
Załóżmy, że chcę obliczyć proporcję różnych wartości w każdej grupie. Na przykład, korzystając z danych mtcars
, Jak obliczyć względną częstotliwość liczby biegów przez am (automatyczny/ręczny) za jednym razem z dplyr
?
library(dplyr)
data(mtcars)
mtcars <- tbl_df(mtcars)
# count frequency
mtcars %>%
group_by(am, gear) %>%
summarise(n = n())
# am gear n
# 0 3 15
# 0 4 4
# 1 4 8
# 1 5 5
Co chciałbym osiągnąć:
am gear n rel.freq
0 3 15 0.7894737
0 4 4 0.2105263
1 4 8 0.6153846
1 5 5 0.3846154
5 answers
Spróbuj tego:
mtcars %>%
group_by(am, gear) %>%
summarise (n = n()) %>%
mutate(freq = n / sum(n))
# am gear n freq
# 1 0 3 15 0.7894737
# 2 0 4 4 0.2105263
# 3 1 4 8 0.6153846
# 4 1 5 5 0.3846154
Gdy grupujesz według wielu zmiennych, każde podsumowanie usuwa jeden poziom grupowania. Ułatwia to stopniowe zwijanie zestawu danych.
Tak więc, po summarise
, zmienna grupująca "gear" jest odrywana, a dane są następnie grupowane "tylko" przez " am " (wystarczy sprawdzić to za pomocą groups
Na danych wynikowych), na których następnie wykonujemy obliczenia mutate
.
Wynik "peeling" jest oczywiście zależny od kolejności grupowania zmiennych w wywołaniu group_by
. Tym razem mieliśmy szczęście, że oddzieliła ona żądaną zmienną. Możesz chcieć wykonać kolejną group_by(am)
, aby uczynić kod bardziej wyraźnym.
Dla zaokrąglenia i prettyfikacji, proszę odnieść się do ładnej odpowiedzi autorstwa @ Tyler Rinker.
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
2018-01-28 17:35:42
Można użyć funkcji count()
, która ma jednak inne zachowanie w zależności od wersji dplyr
:
Dplyr 0.7.1: zwraca tabelę rozgrupowaną {[13] }: należy ponownie grupować według
am
-
Dplyr zgrupowaną tabelę, więc nie trzeba ponownie grupować, chociaż możesz chcieć
ungroup()
dla późniejszych manipulacji
Dplyr 0.7.1
mtcars %>%
count(am, gear) %>%
group_by(am) %>%
mutate(freq = n / sum(n))
Dplyr
mtcars %>%
count(am, gear) %>%
mutate(freq = n / sum(n))
To wyniki w tabeli grouped , jeśli chcesz użyć jej do dalszej analizy, przydatne może być usunięcie atrybutu grouped z ungroup()
.
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
2017-07-19 21:49:42
@ Henrik ' s jest lepsze dla użyteczności, ponieważ spowoduje to, że kolumna będzie znakowana i nie będzie już numeryczna, ale pasuje do tego, o co prosiłeś...
mtcars %>%
group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%"))
## am gear n rel.freq
## 1 0 3 15 79%
## 2 0 4 4 21%
## 3 1 4 8 62%
## 4 1 5 5 38%
EDIT Bo Spacedman o to prosił: -)
as.rel_freq <- function(x, rel_freq_col = "rel.freq", ...) {
class(x) <- c("rel_freq", class(x))
attributes(x)[["rel_freq_col"]] <- rel_freq_col
x
}
print.rel_freq <- function(x, ...) {
freq_col <- attributes(x)[["rel_freq_col"]]
x[[freq_col]] <- paste0(round(100 * x[[freq_col]], 0), "%")
class(x) <- class(x)[!class(x)%in% "rel_freq"]
print(x)
}
mtcars %>%
group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = n/sum(n)) %>%
as.rel_freq()
## Source: local data frame [4 x 4]
## Groups: am
##
## am gear n rel.freq
## 1 0 3 15 79%
## 2 0 4 4 21%
## 3 1 4 8 62%
## 4 1 5 5 38%
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-07-04 18:35:57
Oto ogólna funkcja implementująca rozwiązanie Henrika na dplyr
0.7.1.
freq_table <- function(x,
group_var,
prop_var) {
group_var <- enquo(group_var)
prop_var <- enquo(prop_var)
x %>%
group_by(!!group_var, !!prop_var) %>%
summarise(n = n()) %>%
mutate(freq = n /sum(n)) %>%
ungroup
}
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
2017-07-19 14:18:36
Ta odpowiedź jest oparta na odpowiedzi Matifou.
Najpierw zmodyfikowałem go, aby upewnić się, że kolumna freq nie zostanie zwrócona jako kolumna notacji naukowej za pomocą opcji scipen.
Następnie mnożę odpowiedź przez 100, aby uzyskać procent, a nie dziesiętny, aby kolumna freq była łatwiejsza do odczytania jako procent.
getOption("scipen")
options("scipen"=10)
mtcars %>%
count(am, gear) %>%
mutate(freq = (n / sum(n)) * 100)
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-12-22 11:28:43