R语言进阶笔记4 | dplyr 汇总统计

2021-01-12 14:59:41 浏览数 (1)

之前写过一篇博文(汇总统计?一个函数全部搞定!),介绍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进行格式转换
代码语言:javascript复制
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函数也是一样的:

代码语言:javascript复制
re = dat %>% summarise_all(func) %>% t %>% as.data.frame()
names(re) = c("Max","Min","Range","Mean","SD","CV")
re

5. 更简单的方法

5.1 查看数据

tidyverse这个包,要分析的都是长数据,而不是宽数据,所以我们将其转化为长数据进行分析,会更方便快捷。

代码语言:javascript复制
> 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进行转化:

代码语言:javascript复制
> 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将函数合并在一起:

代码语言:javascript复制
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.

茴香豆的“茴”,有六种写法呢,哈哈……

0 人点赞