2013-05-30 117 views
1

努力學習R,但似乎在SQL中很容易做到的事情上遇到障礙。總結出現併合並在R

問題如下: 我有2個表格: 表A:由'初始命令'組成。這是我們與客戶的第一次聯繫。表B:由「次級訂單」組成,即跟進與初始訂單相關的訂單。

有一對多的關係。 表A具有以下的列:

  • 訂貨號
  • 訂單日期
  • 部件號
  • 客戶ID

表B具有以下的列:

  • 訂單號
  • 訂單日期
  • 部件號
  • 初始順序號

假定每個順序總是爲1的數量,但是我可以在A.在乙多行對於每個初始順序

我想現在要做的是合併這兩個表,但我希望有一個總結,通過B的部件號,聯繫到A.

數據看起來像這樣 答:

Order_Num Order_date Part_Num Cust_ID 
     100 1/1/2013  1001  1111 
     101 1/15/2013  1002  1111 

B:

Order_Num Order_date Part_Num Init_Order_Num 
     200 2/1/2013  2001    100 
     201 3/15/2013  2002    100 
     202 4/18/2013  2002    100 
     203 5/1/2013  2002    101 

我想看到的到底是這樣的:

Order_Num Order_date Part_Num Cust_ID Count_Part_2001 Count_Part_2002 
     100 1/1/2013  1001  1111    1    2 
     101 1/15/2013  1002  1111    1     

我已經通過各種解決方案,這裏包括使用ddply望去,數,彙總,總計等,但似乎沒有工作。數據集有大約2.6米初始訂單和40萬次要訂單。 嘗試使用ddply,即使我將數據設置爲1000次級訂單仍然導致內存不足錯誤(我在機器中有16GB)。

在SQL我會使用一個計數(訂單號),在輔助組中按部件號分組,然後將初始訂單號上的初始訂單表連接起來(還會創建'Count_Part_2001'和'Count_Part_2002'列。Pivot的工作方式與R中的melt()命令相反)。

+2

這聽起來很像你想要使用** data.table **,這將解決你的性能問題,並可能在至多2-3行中完成。但是我們將需要更多R友好格式的示例數據。 – joran

+0

@joran在效率上是正確的,但如果你已經熟悉sql,你可以看看'sqldf'包。 – Justin

+0

我相信示例輸出稍微不正確。最後的「1」應該屬於「Count_Part_2002」,對嗎? – A5C1D2H2I1M1N2O1R2T1

回答

1

如果您的變量以更可比較的方式命名以進行合併,則會更容易。這裏有一個如何你可以用mergeaggregate進行一個例子,其中我剛剛更名的變量:

A <- structure(list(Ord_num_1 = c(100, 101), Ord_date_1 = c(" 1/1/2013 ", 
    " 1/15/2013 "), Part_num = c(1001, 1002), Cust_ID = c(1111,    
    1111)), .Names = c("Ord_num_1", "Ord_date_1", "Part_num", "Cust_ID"  
    ), row.names = 1:2, class = "data.frame") 

B <- structure(list(Ord_num_2 = c(200, 201, 202, 203), Ord_date_2 = c(" 2/1/2013 ", 
    " 3/15/2013 ", " 4/18/2013 ", " 5/1/2013 "), Part_num = c(2001,     
    2002, 2002, 2002), Ord_num_1 = c(100, 100, 100, 101)), .Names = c("Ord_num_2",  
    "Ord_date_2", "Part_num", "Ord_num_1"), row.names = c(NA, 4L), class = "data.frame") 

A和B現在這個樣子:

A 
# Ord_num_1 Ord_date_1 Part_num Cust_ID 
# 1  100 1/1/2013  1001 1111 
# 2  101 1/15/2013  1002 1111 
B 
# Ord_num_2 Ord_date_2 Part_num Ord_num_1 
# 1  200 2/1/2013  2001  100 
# 2  201 3/15/2013  2002  100 
# 3  202 4/18/2013  2002  100 
# 4  203 5/1/2013  2002  101 

讓我們將它們合併:

AB <- merge(A, B, by = "Ord_num_1") 
# Ord_num_1 Ord_date_1 Part_num.x Cust_ID Ord_num_2 Ord_date_2 Part_num.y 
# 1  100 1/1/2013   1001 1111  200 2/1/2013   2001 
# 2  100 1/1/2013   1001 1111  201 3/15/2013   2002 
# 3  100 1/1/2013   1001 1111  202 4/18/2013   2002 
# 4  101 1/15/2013   1002 1111  203 5/1/2013   2002 

而且aggregate他們:

aggregate(Part_num.x ~ Ord_num_1 + Ord_date_1 + Cust_ID + Part_num.y, AB, length) 
# Ord_num_1 Ord_date_1 Cust_ID Part_num.y Part_num.x 
# 1  100 1/1/2013  1111  2001   1 
# 2  100 1/1/2013  1111  2002   2 
# 3  101 1/15/2013  1111  2002   1 

正如@Joran所說,對於大數據,您應該探索data.table包。就這樣,這種方法是非常相似:

library(data.table) 
DTA <- data.table(A, key = "Ord_num_1") ## Important for merging 
DTB <- data.table(B, key = "Ord_num_1") 
DTM <- merge(DTA, DTB) 
DTM[, length(Part_num.x), by = c("Ord_num_1", "Ord_date_1", "Cust_ID", "Part_num.y")] 
# Ord_num_1 Ord_date_1 Cust_ID Part_num.y V1 
# 1:  100 1/1/2013  1111  2001 1 
# 2:  100 1/1/2013  1111  2002 2 
# 3:  101 1/15/2013  1111  2002 1 

正如你所看到的,然而,這兩種解決方案都在「長」格式。這就是說,我發現長格式通常更容易處理。

+0

好吧謝謝所有我會給data.table一槍。 – TheFlyingAfrican

+0

@TheFlyingAfrican,我對[這裏](http://rpubs.com/mrdwab/reshaping-datatable)發生了什麼解釋做了擴充。它也有從長到寬的解決方案,但我不確定它的效率如何。 – A5C1D2H2I1M1N2O1R2T1

0

我對meltdcastreshape函數有一點點運氣。這是基於你想要的最終結果,而不是一個完整的表格合併。 Ananda能夠捕獲表B中的許多其他變量。我也不清楚重塑處理大數據集的能力,因此內存問題可能仍然存在。

從阿難的示例代碼開始:

B <- B[,3:4] 
B$count <- 1 
B 
#Part_num Ord_num_1 count 
#1  2001  100  1 
#2  2002  100  1 
#3  2002  100  1 
#4  2002  101  1 
mB <- melt(B, id=c("Ord_num_1", "Part_num")) 
#mB 
#Ord_num_1 Part_num variable value 
#1  100  2001 count  1 
#2  100  2002 count  1 
#3  100  2002 count  1 
#4  101  2002 count  1 
cB <- dcast(mB, Ord_num_1 + Part_num ~ variable, sum) 
cB 
# Ord_num_1 Part_num count 
#1  100  2001  1 
#2  100  2002  2 
#3  101  2002  1 
reshape(cB, timevar = "Part_num", idvar = "Ord_num_1", direction = "wide") 
#Ord_num_1 count.2001 count.2002 
#1  100   1   2 
#3  101   NA   1 

然後可以合併到一個使用Ord_num_1關鍵。我很想知道你可以在data.table包中找到什麼,我尚未嘗試。