2015-07-10 35 views
2

我想在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 xn矩阵 - 所以我需要unsplit的结果。另外 - 它似乎很慢。我怎样才能改进这个逻辑? 我见过解决方案指向data.table包的方向。我应该使用该软件包重新写入吗?

更新

伟大的答案家伙 - 谢谢!但是 - 我的原始数据框包含更多的列(Feature2 ...),我需要它们在过滤之后全部返回。没有最低的价格(关键/特征1的组合)中的行可以丢弃,所以我不感兴趣,他们的特征2 /特点3

+0

使用什么逻辑值的其他列将被采取?例如,如果'Feature2'对于同一个key-feature1具有不同的值,哪个值必须包含在输出中? – nicola

+0

属于最低价格的价值。所以这件事需要作为一个行过滤器。所以AAA-1,AAA-2,BBB-1的“无论”。其余的行可以被丢弃。 –

回答

3

值可以使用dplyr包:

library(dplyr) 

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

伟大的作品 - 但我需要获得结果中的所有列。我简化了一下这个例子。实际上,数据中包含更多的列,这些列是我在结果中需要的。 –

+0

好的,请参阅编辑 – jeremycg

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 
1

碱基r的解决办法是aggregate(Price ~ Key + Feature1, data, FUN = min)

+0

非常优雅 - 但我需要将所有列都返回到结果中。我简化了一下这个例子。实际上,数据中包含更多的列,这些列是我在结果中需要的。 –

+0

你的意思是你想在你的原始数据框中返回最小值?如果是这种情况,请使用'ave(data $ Price,data $ Key,data $ Feature,FUN = min)'。 – christoph

+0

否 - 查看已更新的问题 - 我只想要最低值的行(对于Key + Feature1的唯一组合) - 但只包含所有原始值。我试过你的代码,它只返回3列:Key,Feature1和Price - 但我也需要所有其他原始列。 –

0

使用R基本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其他办法。