为data.frame中的每个变量组合选择max

时间:2011-11-18 12:15:25

标签: r

我正在努力寻找一种简单的方法来获得产品 - 客户组合的最后付费价格。

customers <-  c("cust_a","cust_b","cust_a","cust_b")
products <- c("prod_a","prod_b","prod_a","prod_b")
dates <- c("2011/10/25","2011/09/14","2011/03/12","2011/05/06")
prices <-c("10","12","15","18")
df <- cbind(customers,products)
df <- cbind(df, dates)
df <- as.data.frame(cbind(df,prices))

接下来,我想为每个客户创建一个新的data.frame - 价格与最高日期的产品组合。在此示例data.frame中,cust_a和prod_1组合将给出10,cust_b和prod_2将给出12。

我知道如何在SQL中执行此操作,但在这种情况下,SQL解决方案不适合我。

3 个答案:

答案 0 :(得分:6)

您可以使用plyr包来解决此类问题:

library(plyr)

dat = data.frame(
  customers =  c("cust_a","cust_b","cust_a","cust_b"),
  products = c("prod_a","prod_b","prod_a","prod_b"),
  dates = c("2011/10/25","2011/09/14","2011/03/12","2011/05/06"),
  prices =c("10","12","15","18")
)

首先使用datesDate列转换为类as.Date。这样可以轻松操作,包括找到最大值:

dat$dates <- as.Date(dat$dates)

接下来,使用ddply。这会将data.frame拆分为块,将函数应用于每个块,然后在组合所有块之后返回data.frame。您要应用于每个块的函数是subset,特别是dates==max(dates)所在的子集:

ddply(dat, .(customers, products), subset, dates==max(dates))

  customers products      dates prices
1    cust_a   prod_a 2011-10-25     10
2    cust_b   prod_b 2011-09-14     12

答案 1 :(得分:2)

您可以使用plyr包来执行此操作。这是解决方案

# CONVERT DATES TO DATE FORMAT
df <- transform(df, dates = as.Date(dates, "%Y/%m/%d"))

# FOR CUSTOMER-PRODUCT COMBINATION, EXTRACT PRICE OF MAX(DATES)
plyr::ddply(df, .(customers, products), summarize, 
  last_price = prices[which.max(dates)])

  customers products last_price
1    cust_a   prod_a         10
2    cust_b   prod_b         12

答案 2 :(得分:1)

如果您的df按日期排序(我可以看到),那么简单的splitlapply就可以完成这项任务:

lapply(split(df, df$customers), function(x) x$prices[1])

如果没有,请在上述行之前订购df,或在内部函数中实现它:)


结果:

> lapply(split(df, df$customers), function(x) x$prices[1])
$cust_a
[1] 10
Levels: 10 12 15 18

$cust_b
[1] 12
Levels: 10 12 15 18

> sapply(split(df, df$customers), function(x) x$prices[1])
cust_a cust_b 
    10     12 
Levels: 10 12 15 18

更新:以上示例仅针对customers运行,因为示例中products没有任何角色。但是对于组合,使用列表作为f的{​​{1}}参数,例如:

split