我试图合并两个data.frames,它们如下所示:
GVKEY YEAR coperol delta vega firm_related_wealth
1 001045 1992 1 38.88885 17.86943 2998.816
2 001045 1993 1 33.57905 19.19287 2286.418
3 001045 1994 1 48.54719 16.85830 3924.053
4 001045 1995 1 111.46762 38.71565 8550.903
5 001045 1996 1 218.89279 45.59413 17834.921
6 001045 1997 1 415.61461 51.45863 34279.515
Run Code Online (Sandbox Code Playgroud)
和
GVKEY YEAR fracdirafter fracdirafterindep twfracdirafter
1 001004 1996 1.00 0.70 1.000000000
2 001004 1997 0.00 0.00 0.000000000
3 001004 1998 0.00 0.00 0.000000000
4 001004 1999 0.00 0.00 0.000000000
5 001004 2000 0.00 0.00 0.000000000
6 001004 2001 0.25 0.25 0.009645437
Run Code Online (Sandbox Code Playgroud)
它们都有1,048,575行.我的代码是merge(a,b,by=c("GVKEY","YEAR"))
,我一直收到错误消息" negative length vectors are not allowed
".我也尝试了data.table方式,但收到错误消息说我的结果将超过2 ^ 31行.显然,合并的数据不会那么大,所以我不知道如何解决这个问题.
您收到此错误,因为连接创建的data.frame
/ data.table
包含多2^31 - 1
行(2,147,483,647).
由于R内部构造向量的方式,任何向量的最大长度都是2^31 - 1
元素(参见:https://stackoverflow.com/a/5234293/2341679).由于a data.frame
/ data.table
实际上是list()
向量,因此该限制也适用于行数.
正如其他人评论和回答的那样,不幸的是你将无法构建这个data.table
,并且由于你们两者之间的重复匹配,它可能会有很多行data.tables
(这些可能或者可能不是你自己的意图).
好消息是,如果重复的匹配不是错误,并且你仍然想要执行连接,那么就有办法解决它:你只需要做任何你想做的计算就可以得到data.table
与连接相同的调用使用data.table[]
运算符,e.g.
:
dt_left[dt_right, on = .(GVKEY, YEAR),
j = .(sum(firm_related_wealth), mean(fracdirafterindep),
by = .EACHI]
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉data.table
语法,可以data.table
使用j
参数对上面的列执行计算.使用此语法j
执行data.table
连接时,将对连接创建的计算进行计算.
这里的关键是by = .EACHI
争论.这会将连接(以及后续计算j
)分解为更小的组件:data.table
每个行中的一个dt_right
和它的匹配dt_left
,避免了创建data.table
with> 2^31 - 1
行的问题.
小智 1
我不确定是如何merge
实现的,但是当您尝试按一列或两列合并时,似乎存在很大的差异,正如您在以下模拟中看到的那样:
> df1<-data.frame(a=1:200000,b=2*(1:200000),c=3*(1:200000))
> df2<-data.frame(a=-df1$a,b=-df1$b,d=4*(1:200000))
> ss<-sample(200000,10000)
> df2[ss,1:2]<-df1[ss,1:2]
> system.time(df3<-merge(x=df1,y=df2,by=c('a','b')))
user system elapsed
1.25 0.00 1.25
> system.time(df4<-merge(x=df1,y=df2,by='a'))
user system elapsed
0.06 0.00 0.06
Run Code Online (Sandbox Code Playgroud)
查看系统内存,两列合并也使用了更多内存。那里可能有一个笛卡尔积,我想这就是导致你的错误的原因。
您可以做的是为每个 data.frame 创建一个连接 GVKEY 和 YEAR 的新列,并按该列合并。
a$newKey<-paste(a$GVKEY,a$YEAR,sep='_')
b$newKey<-paste(b$GVKEY,b$YEAR,sep='_')
c<-merge(a,b,by='newKey')
Run Code Online (Sandbox Code Playgroud)
您需要清理结果中的列,因为 GVKEY 和 YEAR 都会出现两次,但至少合并应该有效。