首页 > 解决方案 > R中的复杂聚合函数构造?

问题描述

可能这并不复杂,但我不知道如何写一个简洁的标题来解释它:

我正在尝试使用 R 中的聚合函数来返回 (1) 数据框中按类别 (cat.2) 的给定列 (val) 的最小值和 (2) 另一列的值 (cat.1 ) 在同一行。我知道如何做第 1 部分,但我无法弄清楚第 2 部分。

数据:

cat.1<-c(1,2,3,4,5,1,2,3,4,5)
cat.2<-c(1,1,1,2,2,2,2,3,3,3)
val<-c(10.1,10.2,9.8,9.7,10.5,11.1,12.5,13.7,9.8,8.9)
df<-data.frame(cat.1,cat.2,val)

> df
   cat.1 cat.2  val
1      1     1 10.1
2      2     1 10.2
3      3     1  9.8
4      4     2  9.7
5      5     2 10.5
6      1     2 11.1
7      2     2 12.5
8      3     3 13.7
9      4     3  9.8
10     5     3  8.9

我知道如何使用聚合来返回每个 cat.2 的最小值:

> aggregate(df$val, by=list(df$cat.2), FUN=min)
  Group.1   x
1       1 9.8
2       2 9.7
3       3 8.9

我无法弄清楚的第二部分是在 df 的同一行上返回 cat.1 中的值,其中聚合为每个 cat.2 找到了 min(df$val)。不确定我是否解释得很好,但这是预期的结果:

> ...
  Group.1   x  cat.1
1       1 9.8      3
2       2 9.7      4
3       3 8.9      5

非常感谢任何帮助。

标签: raggregate

解决方案


如果我们需要 之后的输出aggregate,我们可以merge使用原始数据集

merge(aggregate(df$val, by=list(df$cat.2), FUN=min), 
       df,  by.x = c('Group.1', 'x'), by.y = c('cat.2', 'val'))
#  Group.1   x cat.1
#1       1 9.8     3
#2       2 9.7     4
#3       3 8.9     5

但是,这可以通过在按“cat.2”分组后使用“val”值对行进行切片dplyr来更轻松地完成slicemin

library(dplyr)
df %>% 
    group_by(cat.2) %>% 
    slice(which.min(val))
# A tibble: 3 x 3
# Groups:   cat.2 [3]
# cat.1 cat.2   val
#  <dbl> <dbl> <dbl>
#1     3     1   9.8
#2     4     2   9.7
#3     5     3   8.9

或与data.table

library(data.table)
setDT(df)[, .SD[which.min(val)], cat.2]

或者base R,这可以通过ave

df[with(df, val == ave(val, cat.2, FUN = min)),]
#   cat.1 cat.2 val
#3      3     1 9.8
#4      4     2 9.7
#10     5     3 8.9


推荐阅读