R在另一个数据帧上应用数据帧

时间:2013-10-29 10:15:56

标签: r plyr apply

我有两个数据框。

set.seed(1234)
df <- data.frame( 
  id       = factor(rep(1:24, each = 10)),
  price    = runif(20)*100,
  quantity = sample(1:100,240, replace = T)
  )

df2 <- data.frame(
  id          = factor(seq(1:24)),
  eq.quantity = sample(1:100, 24, replace = T) 
)

我想使用df2$­eq.quantity通过因子变量df$quantity找到与id相比最接近的绝对值。我想为id中的每个df2执行此操作,并将其绑定到一个名为results的新数据框中。

我可以为每个单独的ID这样做:

d.1  <- df2[df2$id == 1, 2]
df.1 <- subset(df, id == 1)
id.1 <- df.1[which.min(abs(df.1$quantity-d.1)),]

哪个会给出解决方案:

id     price      quantity
1      66.60838       84

但我真的希望能够使用更智能的解决方案,并将结果收集到数据框中,所以如果我手动执行它会看起来像这样:

results <- cbind(id.1, id.2, etc..., id.24) 

我在给这个问题好名字时遇到了一些麻烦?

2 个答案:

答案 0 :(得分:2)

data.tables很聪明!

将此添加到您当前的示例...

library(data.table)
dt = data.table(df)
dt2 = data.table(df2)
setkey(dt, id)
setkey(dt2, id)
dt[dt2, dif:=abs(quantity - eq.quantity)]
dt[,list(price=price[which.min(dif)], quantity=quantity[which.min(dif)]), by=id]

结果:

 dt[,list(price=price[which.min(dif)], quantity=quantity[which.min(dif)]), by=id]
    id      price quantity
 1:  1 66.6083758       84
 2:  2 29.2315840       19
 3:  3 62.3379442       63
 4:  4 54.4974836       31
 5:  5 66.6083758        6
 6:  6 69.3591292       13
...

答案 1 :(得分:1)

合并两个数据集并使用lapply对每个id执行该功能。

df3 <- merge(df,df2,all.x=TRUE,by="id")

diffvar <- function(df){ 
df4 <- subset(df3, id == df) 
df4[which.min(abs(df4$quantity-df4$eq.quantity)),]
}

resultslist <- lapply(levels(df3$id),function(df) diffvar(df))

将结果列表元素组合在数据框中:

resultsdf <- data.frame(matrix(unlist(resultslist), ncol=4, byrow=T))

或者更简单:

library(plyr)
resultsdf <- ddply(df3, .(id), function(x)x[which.min(abs(x$quantity-x$eq.quantity)),])