2013-10-01 37 views
2

我是一個絕對的初學者,我希望有人能夠幫助我解決一個合併問題,這個問題在今天晚上的大部分時間都被困住了,並且迄今爲止無法成功針對這個特殊的例子,解決類似的問題。基於矢量鍵合併數據幀

我做了一個虛擬數據幀和矢量來幫助說明我的問題:

dumdata <- data.frame(id=c(1:5), pcode=c(1234,9876,4477,2734,3999), vlo=c(100,450,1000,1325,1500), vhi=c(300,950,1100,1450,1700)) 

id pcode vlo vhi 
1 1234 100 300 
2 9876 450 950 
3 4477 1000 1100 
4 2734 1325 1450 
5 3999 1500 1700 


vkey <- c(105,290,513,1399,1572,1683) 

我想輸出包含dumdata中的情況下,數據的新的數據幀,其中v鍵跌倒的價值變量vlo和vhi之間。實際上,vkey的值總是落在vlo-vhi範圍之間,並且範圍總是離散的。

所需的輸出將如下所示:

id pcode vlo vhi vkey 
1 1234 100 300 105 
1 1234 100 300 290 
2 9876 450 950 513 
4 2734 1325 1450 1399 
5 3999 1500 1700 1572 
5 3999 1500 1700 1683 

回答

4

而不是使用for循環,你可以構建整個指數矢量一氣呵成與sapply

ind <- sapply(vkey, function(x) which(dumdata$vlo < x & x < dumdata$vhi)) 
data.frame(dumdata[ind,], vkey) 

    id pcode vlo vhi vkey 
1 1 1234 100 300 105 
1.1 1 1234 100 300 290 
2 2 9876 450 950 513 
4 4 2734 1325 1450 1399 
5 5 3999 1500 1700 1572 
5.1 5 3999 1500 1700 1683 

如果vkey任何值多行匹配dumdata它變得醜陋不過,因爲你需要使用lapply代替sapply然後做

data.frame(dumdata[unlist(ind),], rep(vkey, sapply(vkey, length))) 

返回所有的比賽,但我從它不會發生的例子中看出來。

編輯:

爲了完整,我會補充一點,你可以使用mapply過,但這主要用於的情況,當你需要做的比較有多個變量(比如,如果你有vkey1vkey2需要一起滿足條件)。

ind <- mapply(function(x, y) which(dumdata$vlo < x & y < dumdata$vhi), 
       vkey1, vkey2) 
+1

由於只有一個參數,它也可以使用'sapply',但很難與成功爭論。 –

+0

當然!我有點sl and,選擇'mapply',因爲有'vlo'和'vhi'> _ <兩個。現在修復它。 – Backlin

+0

我會把'mapply'版本放在底部作爲替代。它具有將其推廣到多參數設置的優點。 (它也有不同的語法。) –

2

使用data.table包。

library(data.table) 

# added a blank vkeyvalue column 
dumdata <- data.table(
    id=c(1:5), 
    pcode=c(1234,9876,4477,2734,3999), 
    vlo=c(100,450,1000,1325,1500), 
    vhi=c(300,950,1100,1450,1700), 
    vkeyvalue = as.integer(NA) 
) 

#initialising the final dataset being populated with the same structure as dumdata 
finalfiltereddata <- dumdata[0] 
vkey <- c(105,290,513,1399,1572,1683) 

# looping throug each key 
for (i in vkey) 
{ 
#subsetting dumdata for values which meet the condition vlo < i & vhi > i 
filtereddata <- dumdata[vlo < i & vhi > i] 

#assigning the filtered data the respective vkeyvalue 
filtereddata[, vkeyvalue := as.integer(i)] 

#appending to the master data set 
finalfiltereddata <- rbind(finalfiltereddata, filtereddata) 
} 

finalfiltereddata 

    # id pcode vlo vhi vkeyvalue 
# 1: 1 1234 100 300  105 
# 2: 1 1234 100 300  290 
# 3: 2 9876 450 950  513 
# 4: 4 2734 1325 1450  1399 
# 5: 5 3999 1500 1700  1572 
# 6: 5 3999 1500 1700  1683 
1

一種選擇可能是使用cut,爲你的「v鍵」變量創建一個匹配的「ID」列如下:

cutBreaks <- sort(unlist(dumdata[c("vlo", "vhi")], use.names = FALSE)) 
cutLabels <- rep(1:nrow(dumdata), each = 2) * c(1, -1) 

new <- data.frame(vals = vkey, id = cut(vkey, breaks = cutBreaks, 
             labels = cutLabels[-length(cutLabels)])) 
new 
# vkey id 
# 1 105 1 
# 2 290 1 
# 3 513 2 
# 4 1399 4 
# 5 1572 5 
# 6 1683 5 

一旦你的,merge應該不會有問題的工作:

merge(new, dumdata) 
# id vkey pcode vlo vhi 
# 1 1 105 1234 100 300 
# 2 1 290 1234 100 300 
# 3 2 513 9876 450 950 
# 4 4 1399 2734 1325 1450 
# 5 5 1572 3999 1500 1700 
# 6 5 1683 3999 1500 1700