2013-05-30 77 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包中找到什么,我尚未尝试。