相对频率/与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 }