2014-02-28 70 views
2

我有兩個非常大的數據集,用於產品的需求和返回(每個數據集約有400萬個條目,但長度不等)。第一個數據集給出[1]需求日期,[2]客戶ID和[3]產品ID。第二個數據集給出了[1]的退貨日期,[2]客戶的ID和[3]產品的ID。有條件地匹配兩個大型數據集彼此的多列中的元素

現在我想匹配給定客戶和產品的所有需求以及同一客戶和產品的回報。成對產品類型和客戶並不是唯一的,因爲客戶可以多次要求產品。因此,我想要將產品的需求與數據集中最早的回報相匹配。也可能發生某些產品未退貨,或者某些產品未退貨(因爲客戶在數據集中的起始數據之前退貨)。

爲此我寫了下面的代碼:

transactionNumber = 1:nrow(demandSet) #transaction numbers for the demandSet 
matchedNumber = rep(0, nrow(demandSet)) #vector of which values in the returnSet correspond to the transactions in the demandSet 

for (transaction in transactionNumber){ 
indices <- which(returnSet[,2]==demandSet[transaction,2]&returnSet[,3]==demandSet[transaction,3]) 
if (length(indices)>0){ 
    matchedNumber[transaction] <- indices[which.min(returnSet[indices,][,1])] #Select the index of the transaction with the minimum date 
} 
} 

然而,這大約需要一天來計算。任何人有更好的建議?請注意0​​的建議在這裏不起作用,因爲match()會溢出內存。

作爲工作的例子,考慮

demandDates = c(1,1,1,5,6,6,8,8) 
demandCustIds = c(1,1,1,2,3,3,1,1) 
demandProdIds = c(1,2,3,4,1,5,2,6) 
demandSet = data.frame(demandDates,demandCustIds,demandProdIds) 

returnDates = c(1,1,4,4,4) 
returnCustIds = c(4,4,1,1,1) 
returnProdIds = c(5,7,1,2,3) 
returnSet = data.frame(returnDates,returnCustIds,returnProdIds) 

(這實際上並不完全正常工作,因爲交易7被錯誤地與回報相匹配4,但是,對於這個問題的緣故讓這個假設我我想要的...我可以稍後修復)

+1

你看過'data.table'嗎? – asb

+0

以前沒有聽說過它,現在就看着它! – Forzaa

+0

如果您更喜歡SQL風格,請查看[sqldf](http://cran.r-project.org/web/packages/sqldf/sqldf.pdf)。 – zx8754

回答

2
require(data.table) 

DD<-data.table(demandSet,key="demandCustIds,demandProdIds") 
DR<-data.table(returnSet,key="returnCustIds,returnProdIds") 
DD[DR,mult="first"] 

    demandCustIds demandProdIds demandDates returnDates 
1:    1    1   1   4 
2:    1    2   1   4 
3:    1    3   1   4 
4:    4    5   NA   1 
5:    4    7   NA   1 
+0

哇,太棒了!你還可以在這裏添加額外的條件嗎?即將需求與具有較大日期而不是數據集中第一個的「第一個」回報相匹配? – Forzaa

+0

肯定的事情 - 嘗試'DD [DR] [returnDates> demandDates,mult =「first」]' – Troy

+0

或'DD [DR] [returnDates> demandDates,.SD [1],by = c(「demandCustIds」,「demandProdIds 「)]' – Troy

相關問題