相对频率/与dplyr的比例
假设我想计算每个组内不同值的比例。 例如,使用mtcars
数据,如何用mtcars
(自动/手动)计算齿轮数量的相对频率?
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
我想实现的是:
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
尝试这个:
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
从dplyr小插图 :
当您通过多个variables进行分组时,每个摘要会剥离分组的一个级别。 这使得逐渐汇总数据集变得容易“。
因此,在summarise
,将分组variables“齿轮”剥离,然后将数据“仅”分组(仅对结果数据进行分组检查),然后进行mutate
计算。
“剥离”的结果当然取决于group_by
调用中分组variables的顺序。 这次我们很幸运,它剥离了所需的variables。 你可能希望做一个后续的group_by(am)
,使你的代码更加明确。
为了圆润和美化,请参阅@Tyler Rinker的好答案。
您可以使用count()
函数,但函数具有不同的行为,具体取决于dplyr
的版本:
-
dplyr 0.7.1:返回一个未分组的表格:你需要再次分组
-
dplyr <0.7.1:返回一个分组表,所以不需要再次分组,虽然你可能想
ungroup()
以便以后的操作
dplyr 0.7.1
mtcars %>% count(am, gear) %>% group_by(am) %>% mutate(freq = n / sum(n))
dplyr <0.7.1
mtcars %>% count(am, gear) %>% mutate(freq = n / sum(n))
如果要将其用于进一步分析,则会生成一个分组表 ,如果使用ungroup()
删除分组属性可能会很有用。
@亨利克的是可用性更好,因为这将使列字符,不再数字,但符合你所要求的…
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%
编辑因为Spacedman要求:-)
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%
这个答案是基于Matifou的回答。
首先,我修改了它,以确保我没有通过使用scipen选项获取作为科学记数法列返回的freq列。
然后我把答案乘以100来得到一个百分比而不是十进制数,使freq列更容易阅读为百分比。
getOption("scipen") options("scipen"=10) mtcars %>% count(am, gear) %>% mutate(freq = (n / sum(n)) * 100)
这是在dplyr
0.7.1上实现Henrik解决scheme的一般function。
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 }