最前面的参考链接:
简单就是左边变成右边
- group_by + summarize 函数
- group_by + filter
- aggregate 函数
- order + !duplicated
- data.table
- do.call + rbind + split + lapply
> library(tidyverse)
> data <- tibble(index1 = rep(c(1, 2), 2),
index2 = rep(c(1, 2), each = 2),
label = letters[1:4]);data
# A tibble: 4 x 3
index1 index2 label
<dbl> <dbl> <chr>
1 1 1 a
2 2 1 b
3 1 2 c
4 2 2 d
# 方法1:便捷易懂,但是筛选后其他列的信息就不在了
# 通过 dplyr 包的 summrize() 函数实现
> data %>%
group_by(index1) %>%
summarize(index2 = min(index2))
# A tibble: 2 x 2
index1 index2
<dbl> <dbl>
1 1 1
2 2 1
# 方法2:通过 filter() 函数来实现
> data %>%
group_by(index1) %>%
filter(index2 == min(index2))
# A tibble: 2 x 3
# Groups: index1 [2]
index1 index2 label
<dbl> <dbl> <chr>
1 1 1 a
2 2 1 b
# 方法3:简单,但是没接触的第一次可能不大懂,且筛选后其他列的信息就不在了
# aggregate() 函数
# aggregate(cbind(value1, value2, ...) ~ group1 + group2 + ..., data, FUN = 函数)
> aggregate(index2~index1, data, function(x) x[which.min(abs(x))])
index1 index2
1 1 1
2 2 1
# 方法4:稍微显得冗余,但是能保留之前所有的列
> data1 <- data[order(data$index1, data$index2, decreasing = FALSE), ]
> data1[!duplicated(data1$index1), ]
# A tibble: 2 x 3
index1 index2 label
<dbl> <dbl> <chr>
1 1 1 a
2 2 1 b
# 方法5:data.table,在 R 中出了名的高效处理包,但是不易理解,但是有人封装成了 tidyfst 包
# 且能保留原本所有列
> library(data.table)
> as.data.table(data)[, .SD[which.min(abs(index2))], by = index1]
index1 index2 label
1: 1 1 a
2: 2 1 b
# 方法6:利用 do.call 函数和 split 函数 结合 lapply 以及 rbind
# lapply 故名思议对 list 进行 apply 批量操作
> do.call(rbind, lapply(split(data,data$index1),function(x) x[which.min(abs(data$index2)),]))
# A tibble: 2 x 3
index1 index2 label
* <dbl> <dbl> <chr>
1 1 1 a
2 2 1 b
简单拓展:aggreagte
书上有一句话:不幸的是 aggregate 函数运行得相当慢
来源书籍
英文名 《R for everyone: Adavanced Analytics and Graphics 2nd》
中文名 《R 语言:实用数据分析和可视化技术 第 2 版》
中文第 103 页开始 aggregate 函数
aggregate(value ~ group, data, FUN = 函数)
value:表示要计算的列,可以通过 cbind() 函数来衔接多个列分组
group:表示要分组的列,可以通过 + 来衔接多个列分组
data:数据
FUN:表示要进行的操作
# 单列分组
> aggregate(price ~ cut, diamonds, FUN = mean)
cut price
1 Fair 4358.758
2 Good 3928.864
3 Very Good 3981.760
4 Premium 4584.258
5 Ideal 3457.542
# 多列分组
> aggregate(price ~ cut + color, diamonds, FUN = mean) %>% head(5)
cut color price
1 Fair D 4291.061
2 Good D 3405.382
3 Very Good D 3470.467
4 Premium D 3631.293
5 Ideal D 2629.095
# 多列计算
> aggregate(cbind(price, carat) ~ cut, diamonds, FUN = mean) %>% head(5)
cut price carat
1 Fair 4358.758 1.0461366
2 Good 3928.864 0.8491847
3 Very Good 3981.760 0.8063814
4 Premium 4584.258 0.8919549
5 Ideal 3457.542 0.7028370
# 多列值 + 多列变量
> aggregate(cbind(price, carat) ~ cut + color, diamonds, FUN = mean) %>% head(5)
cut color price carat
1 Fair D 4291.061 0.9201227
2 Good D 3405.382 0.7445166
3 Very Good D 3470.467 0.6964243
4 Premium D 3631.293 0.7215471
5 Ideal D 2629.095 0.5657657