2013-10-29 197 views
1

我有兩個數據幀。R在另一個數據幀上應用數據幀

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。我想爲的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

你確定你的 「解決方案」 是正確的? – nsheff

+0

您的權利,我在設置種子之前執行了其中一個數據集....現在在帖子中更改了它。 – NoThanks

回答

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)),]) 
+0

謝謝,我希望你能很快啓發我:我不明白'子集(df3,id == df)'是幹什麼的?或者我理解它,但你不能在控制檯中使用它?另外,它是做什麼,你寫'功能(df)diffvar(df))'而不是'diffvar(df)'? – NoThanks

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 
...