通过两列的唯一组合获得最小分组

时间:2015-07-10 15:19:47

标签: r

我在R中想要实现的目标如下:给出一个表(在我的情况下是数据框) - 我希望得到两个列的每个唯一组合的最低价格。

例如,给出下表:

+-----+-----------+-------+----------+----------+
| Key | Feature1  | Price | Feature2 | Feature3 |
+-----+-----------+-------+----------+----------+
| AAA |         1 |   100 | whatever | whatever |
| AAA |         1 |   150 | whatever | whatever |
| AAA |         1 |   200 | whatever | whatever |
| AAA |         2 |   110 | whatever | whatever |
| AAA |         2 |   120 | whatever | whatever |
| BBB |         1 |   100 | whatever | whatever |
+-----+-----------+-------+----------+----------+

我想要一个看起来像的结果:

+-----+-----------+-------+----------+----------+
| Key | Feature1  | Price | Feature2 | Feature3 |
+-----+-----------+-------+----------+----------+
| AAA |         1 |   100 | whatever | whatever |
| AAA |         2 |   110 | whatever | whatever |
| BBB |         1 |   100 | whatever | whatever |
+-----+-----------+-------+----------+----------+

所以我正在制定一个解决方案:

s <- lapply(split(data, list(data$Key, data$Feature1)), function(chunk) { 
        chunk[which.min(chunk$Price),]})

但结果是1 x n矩阵 - 所以我需要unsplit结果。而且 - 它似乎很慢。我该如何改进这种逻辑? 我已经看到指向data.table包的方向的解决方案。我应该使用该软件包重写吗?

更新

很棒的答案 - 谢谢!但是 - 我的原始数据帧包含更多列(Feature2 ...),我在过滤后需要它们全部返回。没有最低价格的行(对于Key / Feature1的组合)可以被丢弃,所以我对Feature2 / Feature3的值不感兴趣

4 个答案:

答案 0 :(得分:3)

您可以使用dplyr包:

library(dplyr)

data %>% group_by(Key, Feature1) %>%
         slice(which.min(Price))

答案 1 :(得分:3)

由于您提到data.table包,我在此提供使用该包的解决方案:

library(data.table)
setDT(df)[,.(Price=min(Price)),.(Key, Feature1)] #initial question
setDT(df)[,.SD[which.min(Price)],.(Key, Feature1)] #updated question

df是您的示例data.frame。

更新:使用mtcars数据进行测试

df<-mtcars
library(data.table)
setDT(df)[,.SD[which.min(mpg)],by=am]
   am  mpg cyl disp  hp drat   wt  qsec vs gear carb
1:  1 15.0   8  301 335 3.54 3.57 14.60  0    5    8
2:  0 10.4   8  472 205 2.93 5.25 17.98  0    3    4

答案 2 :(得分:1)

基础R解决方案是aggregate(Price ~ Key + Feature1, data, FUN = min)

答案 3 :(得分:0)

使用R base aggregate

> aggregate(Price~Key+Feature1, min, data=data)
  Key Feature1 Price
1 AAA        1   100
2 BBB        1   100
3 AAA        2   110

See this post其他替代方案。