- 使用tidyverse包可以方便地进行分组处理。
> data
name id grade
1 a 1 60
2 a 2 NA
3 b 3 60
4 c 4 80
5 c 5 60
6 c 6 60
可以对不同class进行分组,并作相应地统计。
library(tidyverse)
- 对name分组后计数
n()不支持对某一字段计数,也不能用中括号限定条件。
> data %>% group_by(name) %>% summarise(count = n())
# A tibble: 3 x 2
name count
<fct> <int>
1 a 2
2 b 1
3 c 3
- 对grade去重后计数
这里的n_distinct()可以支持用中括号对符合某条件的数据进行计数。
#也可以写成 summarise(n_distinct(grade[id>3])),只统计id大于3的数量。
> data %>% group_by(name) %>% summarise(n_distinct(grade))
# A tibble: 3 x 2
name `n_distinct(grade)`
<fct> <int>
1 a 2
2 b 1
3 c 2
- 统计grade字段中非NA的数量。逻辑结果中,TRUE的值为1,FALSE的值为0。
> data %>% group_by(name) %>% summarise(count = sum(!is.na(grade)))
# A tibble: 3 x 2
name count
<fct> <int>
1 a 1
2 b 1
3 c 3
- 求grade的平均值, 不考虑NA。
> data %>% group_by(name) %>% summarise(mean = mean(grade, na.rm = T))
# A tibble: 3 x 2
name mean
<fct> <dbl>
1 a 60
2 b 60
3 c 66.7
- 求grade的平均值,但只考虑id为奇数的记录。这里是可以在分组内指定条件的,像sql中的having, 中括号中的语句就是限定的条件,中括号前的内容是要统计的字段。
> data %>% group_by(name) %>% summarise(mean = mean(grade[id%%2 == 1], na.rm = T))
# A tibble: 3 x 2
name mean
<fct> <dbl>
1 a 60
2 b 60
3 c 60
- 统计每个分组下,grade字段中值为60的的记录所占的比例,可以巧妙地使用平均函数与逻辑判断。
> data %>% group_by(name) %>% summarise(ratio = mean(grade == 60, na.rm = T))
# A tibble: 3 x 2
name ratio
<fct> <dbl>
1 a 1
2 b 1
3 c 0.667
参考文章:
R for Data Science