2015-08-26 55 views
4

中執行復雜的多列匹配我希望基於多個列上的條件來匹配兩個數據幀,但無法弄清楚。因此,如果有我的數據集:如何在R/

df1 <- data.frame(lower=c(0,5,10,15,20), upper=c(4,9,14,19,24), x=c(12,45,67,89,10)) 
df2 <- data.frame(age=c(12, 14, 5, 2, 9, 19, 22, 18, 23)) 

我想從DF2落入其目的在DF1下限和上限之間的範圍內添加一個額外的列DF2含x的DF1值相匹配年齡年齡介於上限和下限之間。即我想df2看起來像

age x 
12 67 
14 67 
5 45 
....etc. 

我該如何實現這樣的匹配?

回答

6

我會去用一個簡單的sapply,並在df1$x選擇這樣的「相與」條件:

df2$x <- sapply(df2$age, function(x) { df1$x[ x >= df1$lower & x <= df1$upper ] }) 

這給:

> df2 
    age x 
1 12 67 
2 14 67 
3 5 45 
4 2 12 
5 9 45 
6 19 89 
7 22 10 
8 18 89 
9 23 10 

12歲比如裏面的選擇括號給出:

> 12 >= df1$lower & 12 <= df1$upper 
[1] FALSE FALSE TRUE FALSE FALSE 

所以得到這個邏輯向量很容易爲你的範圍沒有重疊

+0

感謝Tensibai我喜歡它。是的,我故意構建這種方式。在我的真實數據中,它並不那麼幹淨,但我可以輕鬆解決它。我喜歡使用> =和<=我發現比其他解決方案更容易閱讀。 – user2498193

6

data.table使用foverlaps是你在找什麼:

library(data.table) 
setDT(df1) 
setDT(df2)[,age2:=age] 
setkey(df1,lower,upper) 
foverlaps(df2, df1, by.x = names(df2),by.y=c("lower","upper"))[,list(age,x)] 

# age x 
# 1: 12 67 
# 2: 14 67 
# 3: 5 45 
# 4: 2 12 
# 5: 9 45 
# 6: 19 89 
# 7: 22 10 
# 8: 18 89 
# 9: 23 10 
+0

感謝agstudy。非常好。難道我更喜歡Tensabai發佈的sapply版本 - 我目前沒有在我的項目中使用data.table,我喜歡它保持它在基礎r – user2498193

6

這裏有一個熔化的數據使用findInterval設置

另一量化方法
library(data.table) 
df2$x <- melt(setDT(df1), "x")[order(value), x[findInterval(df2$age, value)]] 
# age x 
# 1 12 67 
# 2 14 67 
# 3 5 45 
# 4 2 12 
# 5 9 45 
# 6 19 89 
# 7 22 10 
# 8 18 89 
# 9 23 10 

這裏的想法是

  • 首先,收拾你的數據,以便lowerupper將在同一列中並且x將具有對應值,以該新的列,
  • 然後,根據這些範圍(必要findInterval)中的數據進行排序。
  • 最後,運行x列中findInterval,以便找到正確的發病率

這裏還有一個可能dplyr/tidyr版本

library(tidyr) 
library(dplyr) 
df1 %>% 
    gather(variable, value, -x) %>% 
    arrange(value) %>% 
    do(data.frame(x = .$x[findInterval(df2$age, .$value)])) %>% 
    cbind(df2, .) 
# age x 
# 1 12 67 
# 2 14 67 
# 3 5 45 
# 4 2 12 
# 5 9 45 
# 6 19 89 
# 7 22 10 
# 8 18 89 
# 9 23 10 
+0

謝謝大衛。也非常好。再次,我的偏好(可能非理性)是基於R sapply版本 – user2498193

+1

是的,你可以使用你喜歡的任何版本,雖然'sapply'不是矢量化的,並且對於大數據集可能會更慢。 –

+0

好的,謝謝大衛。在這個特定的例子中,數據集很小。但我將來會忍受這一點。感謝您的輸入! – user2498193