我有两个数据框。
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)
我在给这个问题好名字时遇到了一些麻烦?
答案 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)),])