在 dplyr 中按组获得总和后计算具有行百分比的列
Calculating columns with row percentage after obtaining sums by group in dplyr
我正在使用 dplyr
为两个类别生成一个简单的摘要 table:
# Data
data("mtcars")
# Lib
require(dplyr)
# Summary
mt_sum <- mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n)
产生预期的结果:
Source: local data frame [3 x 3]
gear 0 1
(dbl) (int) (int)
1 3 15 NA
2 4 4 8
3 5 NA 5
对于生成的table,我想添加一组列,这些列将具有行百分比而不是当前可用的总计。
想要的结果
我希望我的 table 看起来像这样:
gear 0 1 0per 1per
1 3 15 NA 100%
2 4 4 8 33% 67%
3 5 NA 5 100%
尝试
我尝试通过添加代码来实现以下目标:
mt_sum <- mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n) %>%
mutate_each(funs(./rowSums(.)))
但是returns出现以下错误:
Error: 'x' must be an array of at least two dimensions
因此我的问题是:如何在 dplyr
中添加带有行百分比值的额外列?
侧分
- 我更喜欢空白值而不是
NAs
- table 可以使用
gmodels
中的 CrossTable
轻松构建,但我想留在 dplyr
中,因为我想保留尽可能多的转换可能在一个地方
我想这就是你需要的:
# Data
data("mtcars")
# Lib
require(dplyr)
require(tidyr)
require(scales) #for percent
# Summary
mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n) %>%
#you need rowwise because this is a rowwise operation
rowwise %>%
#I find do to be the best function for ad-hoc things that
#have no specific dplyr function
#I use do below to calculate the numeric percentages
do(data.frame(.,
per0 = .$`0` / sum(.$`0`, .$`1`, na.rm=TRUE),
per1 = .$`1` / sum(.$`0`, .$`1`, na.rm=TRUE))) %>%
#mutate here is used to convert NAs to blank and numbers to percentages
mutate(per0 = ifelse(is.na(per0), '', percent(per0)),
per1 = ifelse(is.na(per1), '', percent(per1)))
输出:
Source: local data frame [3 x 5]
Groups: <by row>
gear X0 X1 per0 per1
(dbl) (int) (int) (chr) (chr)
1 3 15 NA 100%
2 4 4 8 33.3% 66.7%
3 5 NA 5 100%
所以这部分完成了,但并没有在一个表达式中完成所有操作,也没有重命名变量。 @LyzandeR 的解决方案更好。
library(tidyr)
library(dplyr)
mt_sum <- mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n, fill=0)
row_sum <- rowSums(mt_sum[,2:3])
mt_sum <- mutate_each(mt_sum[,2:3],funs(./row_sum)) %>% bind_cols(mt_sum)
这里有一个重塑的方法:
图书馆(dplyr)
图书馆(整理)
mtcars %>%
count(gear, am) %>%
mutate(percent = n / sum(n)) %>%
gather(variable, value,
n, percent) %>%
unite("new_variable", am, variable) %>%
spread(new_variable, value)
我正在使用 dplyr
为两个类别生成一个简单的摘要 table:
# Data
data("mtcars")
# Lib
require(dplyr)
# Summary
mt_sum <- mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n)
产生预期的结果:
Source: local data frame [3 x 3]
gear 0 1
(dbl) (int) (int)
1 3 15 NA
2 4 4 8
3 5 NA 5
对于生成的table,我想添加一组列,这些列将具有行百分比而不是当前可用的总计。
想要的结果
我希望我的 table 看起来像这样:
gear 0 1 0per 1per
1 3 15 NA 100%
2 4 4 8 33% 67%
3 5 NA 5 100%
尝试
我尝试通过添加代码来实现以下目标:
mt_sum <- mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n) %>%
mutate_each(funs(./rowSums(.)))
但是returns出现以下错误:
Error: 'x' must be an array of at least two dimensions
因此我的问题是:如何在 dplyr
中添加带有行百分比值的额外列?
侧分
- 我更喜欢空白值而不是
NAs
- table 可以使用
gmodels
中的CrossTable
轻松构建,但我想留在dplyr
中,因为我想保留尽可能多的转换可能在一个地方
我想这就是你需要的:
# Data
data("mtcars")
# Lib
require(dplyr)
require(tidyr)
require(scales) #for percent
# Summary
mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n) %>%
#you need rowwise because this is a rowwise operation
rowwise %>%
#I find do to be the best function for ad-hoc things that
#have no specific dplyr function
#I use do below to calculate the numeric percentages
do(data.frame(.,
per0 = .$`0` / sum(.$`0`, .$`1`, na.rm=TRUE),
per1 = .$`1` / sum(.$`0`, .$`1`, na.rm=TRUE))) %>%
#mutate here is used to convert NAs to blank and numbers to percentages
mutate(per0 = ifelse(is.na(per0), '', percent(per0)),
per1 = ifelse(is.na(per1), '', percent(per1)))
输出:
Source: local data frame [3 x 5]
Groups: <by row>
gear X0 X1 per0 per1
(dbl) (int) (int) (chr) (chr)
1 3 15 NA 100%
2 4 4 8 33.3% 66.7%
3 5 NA 5 100%
所以这部分完成了,但并没有在一个表达式中完成所有操作,也没有重命名变量。 @LyzandeR 的解决方案更好。
library(tidyr)
library(dplyr)
mt_sum <- mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
spread(key = am, value = n, fill=0)
row_sum <- rowSums(mt_sum[,2:3])
mt_sum <- mutate_each(mt_sum[,2:3],funs(./row_sum)) %>% bind_cols(mt_sum)
这里有一个重塑的方法:
图书馆(dplyr) 图书馆(整理)
mtcars %>%
count(gear, am) %>%
mutate(percent = n / sum(n)) %>%
gather(variable, value,
n, percent) %>%
unite("new_variable", am, variable) %>%
spread(new_variable, value)