之前写过一篇博文(汇总统计?一个函数全部搞定!),介绍R中编写一个函数,进行汇总统计。效果很不错。今天用tidyverse
包实现一下,多角度尝试,然后尝试中学习。
1. 想要达到的效果
最近,一个朋友让我帮忙做一个图标,是这个样子的:
相关的统计参数:
- 最大值
- 最小值
- 极差
- 平均值
- 标准差
- 变异系数
2. 模拟数据
首先,我模拟一个20行5列的数据框,每一列都是数值的数据类型。
代码语言:javascript复制set.seed(123)
dat = as.data.frame(matrix(rnorm(100) 100,20))
head(dat)
数据预览如下:
代码语言:javascript复制> head(dat)
V1 V2 V3 V4 V5
1 99.43952 98.93218 99.30529 100.37964 100.00576
2 99.76982 99.78203 99.79208 99.49768 100.38528
3 101.55871 98.97400 98.73460 99.66679 99.62934
4 100.07051 99.27111 102.16896 98.98142 100.64438
5 100.12929 99.37496 101.20796 98.92821 99.77951
6 101.71506 98.31331 98.87689 100.30353 100.33178
3. 常规方法
3.1 编写函数
代码语言:javascript复制huizong = function (dd) {
func <- function(x) {
c(Max = max(x, na.rm = T),
Min = min(x, na.rm = T),
Range = max(x,na.rm = T) - min(x,na.rm = T),
Mean = mean(x, na.rm = T),
SD = sd(x, na.rm = T),
CV = sd(x, na.rm = T)/mean(x, na.rm = T) * 100)
}
sm <- as.data.frame(t(apply(dd, 2, func)))
return(sm)
}
「代码解释」
- 首先定义一个
func
的函数,里面包括最大值
,最小值
,极差
,标准差
,变异系数
。 - 然后使用
apply
函数,对数据框的列进行操作 - 最后返回汇总统计的结果
- 该函数的对象为一个由变量组成的数据框,数据类型都要是
数值
3.2 函数测试
代码语言:javascript复制> huizong(dat)
Max Min Range Mean SD CV
V1 101.7869 98.03338 3.753530 100.14162 0.9726653 0.9712897
V2 101.2538 98.31331 2.940508 99.94874 0.8299387 0.8303643
V3 102.1690 98.45125 3.717709 100.10649 0.9573406 0.9563222
V4 102.0501 97.69083 4.359254 99.88008 0.9731062 0.9742745
V5 102.1873 98.97358 3.213754 100.37509 0.8289955 0.8258976
4. dplyr
的方法
4.1 编写函数
处理流程:
- 首先定义一个
func
函数,计算相关的汇总参数 - 使用
summarise_if
函数,或者summarise_all
函数,计算汇总统计 - 使用
t()
进行转置 - 使用
as.data.frame
进行格式转换
func = function(x) {
c(Max = max(x, na.rm = T),
Min = min(x, na.rm = T),
Range = max(x,na.rm = T) - min(x,na.rm = T),
Mean = mean(x, na.rm = T),
SD = sd(x, na.rm = T),
CV = sd(x, na.rm = T)/mean(x, na.rm = T) * 100)
}
4.2 函数测试
可以看到,summarise_all
函数也是一样的:
re = dat %>% summarise_all(func) %>% t %>% as.data.frame()
names(re) = c("Max","Min","Range","Mean","SD","CV")
re
5. 更简单的方法
5.1 查看数据
tidyverse
这个包,要分析的都是长数据,而不是宽数据,所以我们将其转化为长数据进行分析,会更方便快捷。
> dat
V1 V2 V3 V4 V5
1 99.43952 98.93218 99.30529 100.37964 100.00576
2 99.76982 99.78203 99.79208 99.49768 100.38528
3 101.55871 98.97400 98.73460 99.66679 99.62934
4 100.07051 99.27111 102.16896 98.98142 100.64438
5 100.12929 99.37496 101.20796 98.92821 99.77951
6 101.71506 98.31331 98.87689 100.30353 100.33178
7 100.46092 100.83779 99.59712 100.44821 101.09684
8 98.73494 100.15337 99.53334 100.05300 100.43518
9 99.31315 98.86186 100.77997 100.92227 99.67407
10 99.55434 101.25381 99.91663 102.05008 101.14881
11 101.22408 100.42646 100.25332 99.50897 100.99350
12 100.35981 99.70493 99.97145 97.69083 100.54840
13 100.40077 100.89513 99.95713 101.00574 100.23873
14 100.11068 100.87813 101.36860 99.29080 99.37209
15 99.44416 100.82158 99.77423 99.31199 101.36065
16 101.78691 100.68864 101.51647 101.02557 99.39974
17 100.49785 100.55392 98.45125 99.71523 102.18733
18 98.03338 99.93809 100.58461 98.77928 101.53261
19 100.70136 99.69404 100.12385 100.18130 99.76430
20 99.52721 99.61953 100.21594 99.86111 98.97358
5.2 转化为宽数据
这里,我们所要分析的是y1,y2,y3,y4,y5的汇总统计结果,所以将其转化为数据,使用tidyr
中的pivot_longer
进行转化:
> d1 = pivot_longer(dat,1:5,names_to = "Trait",values_to = "values")
> head(d1)
# A tibble: 6 x 2
Trait values
<chr> <dbl>
1 V1 99.4
2 V2 98.9
3 V3 99.3
4 V4 100.
5 V5 100.
6 V1 99.8
5.3 汇总统计
然后使用group_by函数,和summarise函数,进行汇总统计:
代码语言:javascript复制d1 %>% group_by(Trait) %>% summarise(Max = max(values),
Min = min(values),
Mean = mean(values,na.rm=T),
SD = sd(values,na.rm = T),
CV = sd(values,na.rm = T)/mean(values,na.rm=T))
「代码解释:」
- 使用group_by函数进行分组
- 使用summarise进行汇总统计,里面是不同的汇总统计参数
5.4 查看结果
代码语言:javascript复制> d1 %>% group_by(Trait) %>% summarise(Max = max(values),
Min = min(values),
Mean = mean(values,na.rm=T),
SD = sd(values,na.rm = T),
CV = sd(values,na.rm = T)/mean(values,na.rm=T))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 5 x 6
Trait Max Min Mean SD CV
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 V1 102. 98.0 100. 0.973 0.00971
2 V2 101. 98.3 99.9 0.830 0.00830
3 V3 102. 98.5 100. 0.957 0.00956
4 V4 102. 97.7 99.9 0.973 0.00974
5 V5 102. 99.0 100. 0.829 0.00826
结果完全一致!
6. 更上一层楼
使用summarise_at
函数,然后使用list将函数合并在一起:
d1 %>%
group_by(Trait) %>%
summarise_at(vars(values), list(Min = min, Mean = mean, Max = max, Sd = sd,range = sum))
「结果如下:」
代码语言:javascript复制> d1 %>%
group_by(Trait) %>%
summarise_at(vars(values), list(Min = min, Mean = mean, Max = max, Sd = sd,range = sum))
# A tibble: 5 x 6
Trait Min Mean Max Sd range
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 V1 98.0 100. 102. 0.973 2003.
2 V2 98.3 99.9 101. 0.830 1999.
3 V3 98.5 100. 102. 0.957 2002.
4 V4 97.7 99.9 102. 0.973 1998.
5 V5 99.0 100. 102. 0.829 2008.
茴香豆的“茴”,有六种写法呢,哈哈……