5

我刚刚尝试在具有 64G 内存的机器上合并 R 3.0.1 中的两个表并得到以下错误。帮助将不胜感激。(data.table 版本为 1.8.8)

这是我的代码的样子:

library(parallel)
library(data.table)

data1:几百万行和 3 列。列是tag和。有 750K 的唯一值,每个 1 到 1000秒,有 5000 个可能的值。取任何正的实际值。prodvtagprodtagprodv

setkey(data1, tag)
merge (data1, data1, allow.cartesian=TRUE)

我收到以下错误:

vecseq(f_ , len _, if (allow.cartesian) NULL else as.integer(max(nrow(x), : Join 导致超过 2^31 行(内部 vecseq 达到物理限制)中的错误。很可能是错误指定的连接. 检查 i 中的重复键值,每个键值都一遍又一遍地加入 x 中的同一组。如果没关系,请尝试包含j和删除by(by-without-by) 以便 j 为每个组运行以避免大否则,请在 FAQ、Wiki、Stack Overflow 和 datatable-help 中搜索此错误消息以获取建议。调用:merge -> merge.data.table -> [ -> [.data.table -> vecseq

显示 by-without-by 的新示例

country = fread("
country product share
1 5 .2
1 6 .2
1 7 .6
2 6 .3
2 7 .1
2 8 .4
2 9 .2
")
prod = fread("
prod period value
5 1990 2
5 1991 3
5 1992 2
5 1993 4
5 1994 3
5 1995 5
6 1990 1
6 1991 1
6 1992 0
6 1993 4
6 1994 8
6 1995 2
7 1990 3
7 1991 3
7 1992 3
7 1993 4
7 1994 7
7 1995 1
8 1990 2
8 1991 4
8 1992 2
8 1993 4
8 1994 2
8 1995 6
9 1990 1
9 1991 2
9 1992 4
9 1993 4
9 1994 5
9 1995 6
")

似乎完全不可能选择共享国家标签的市场子集,找到这些对中的协方差,并按国家/地区进行整理而不违反规模限制。这是我迄今为止最好的镜头:

setkey(country,country)
setkey(prod, prod, period)
covars <- setkey(setkey(unique(country[country, allow.cartesian=T][, c("prod","prod.1"), with=F]),prod)[prod, allow.cartesian=T], prod.1, period)[prod, ] [ , list(pcov = cov(value,value.1)), by=list(prod,prod.1)] # really long oneliner that finds unique market pairs from the the self-join, merges it with the second table and calculates covariances from the merged table.
clevel <-setkey(country[country, allow.cartesian = T], prod, prod.1)[covars, nomatch=0][ , list(countryvar = sum(share*share.1*pcov)), by="country"]
> clevel
   country countryvar
1:       1   2.858667
2:       2   1.869667

当我对任何合理大小的数据尝试这种方法时,我遇到了 vecseq 错误。如果 data.table 在 2^31 限制下没有那么犹豫,那就太好了。我是这个包的粉丝。关于如何使用更多 j 规范的建议也将不胜感激。(鉴于我必须如何计算两个数据表交集的差异,我不确定如何尝试 J 规范)。

4

2 回答 2

4

R 3.0.1支持长度大于 2^31 - 1 的对象。虽然基础 R 附带的包已经可以创建此类对象,但贡献的包是否可以这样做取决于包。基本上,任何使用编译代码的包都必须重新编译并可能修改以利用此功能。

此外,假设 64GB RAM 足以处理 60GB 对象是一种乐观。

于 2013-08-07T13:22:13.317 回答
3

此连接确实似乎指定错误。一般来说,我认为,具有单列键的表的自连接可能总是被错误指定。考虑以下示例:

> DT
   A B
1: 1 5
2: 1 6
3: 1 7
4: 2 8
5: 2 9
> setkey(DT,A)

A 有 2 个唯一值(1 和 2),但它们在 A 列中重复。键是单列。

> DT[DT]   # the long error message

> DT[DT, allow.cartesian=TRUE]  # **each row** of DT is self joined to DT
    A B B.1
 1: 1 5   5
 2: 1 6   5
 3: 1 7   5
 4: 1 5   6
 5: 1 6   6
 6: 1 7   6
 7: 1 5   7
 8: 1 6   7
 9: 1 7   7
10: 2 8   8
11: 2 9   8
12: 2 8   9
13: 2 9   9

这真的是您需要的结果吗?更有可能的是,需要通过向键添加更多列来更改查询,by而不是执行自联接或错误消息中的提示。

有关合并后您需要实现的目标的更多信息(大图)可能会有所帮助。

“包括 j 并删除 (by-without-by) 以便 j 为每个组运行以避免大分配”的示例(请参阅有问题的错误消息)

现在讨论的示例(协方差)通常使用矩阵而不是 data.table 完成。但无论如何要继续快速演示,只需将其用作示例数据......

require(data.table)
country = fread("
Country Product
1 5
1 6
1 7
2 6
2 7
2 8
2 9
")
prod = fread("
Prod1 Prod2 Covariance
5 5 .4
5 6 .5
5 7 .6
5 8 -.3
5 9 -.1
6 6 .3
6 7 .2
6 8 .4
6 9 -.2
7 7 .2
7 8 .1
7 9 .3
8 8 .1
8 9 .6
9 9 .01
")

.

country
   Country Product
1:       1       5
2:       1       6
3:       1       7
4:       2       6
5:       2       7
6:       2       8
7:       2       9
prod
    Prod1 Prod2 Covariance
 1:     5     5       0.40
 2:     5     6       0.50
 3:     5     7       0.60
 4:     5     8      -0.30
 5:     5     9      -0.10
 6:     6     6       0.30
 7:     6     7       0.20
 8:     6     8       0.40
 9:     6     9      -0.20
10:     7     7       0.20
11:     7     8       0.10
12:     7     9       0.30
13:     8     8       0.10
14:     8     9       0.60
15:     9     9       0.01

.

setkey(country,Country)
country[country,{print(.SD);print(i.Product)}]
# included j to demonstrate j running for each row of i. Just printing to demo.
   Product
1:       5
2:       6
3:       7
[1] 5
   Product
1:       5
2:       6
3:       7
[1] 6
   Product
1:       5
2:       6
3:       7
[1] 7
   Product
1:       6
2:       7
3:       8
4:       9
[1] 6
   Product
1:       6
2:       7
3:       8
4:       9
[1] 7
   Product
1:       6
2:       7
3:       8
4:       9
[1] 8
   Product
1:       6
2:       7
3:       8
4:       9
[1] 9
Empty data.table (0 rows) of 2 cols: Country,Product

.

setkey(prod,Prod1,Prod2)
country[country,prod[J(i.Product,Product),Covariance,nomatch=0]]
    Country Prod1 Prod2 Covariance
 1:       1     5     5       0.40
 2:       1     5     6       0.50
 3:       1     5     7       0.60
 4:       1     6     6       0.30
 5:       1     6     7       0.20
 6:       1     7     7       0.20
 7:       2     6     6       0.30
 8:       2     6     7       0.20
 9:       2     6     8       0.40
10:       2     6     9      -0.20
11:       2     7     7       0.20
12:       2     7     8       0.10
13:       2     7     9       0.30
14:       2     8     8       0.10
15:       2     8     9       0.60
16:       2     9     9       0.01

country[country, prod[J(i.Product,Product),Covariance,nomatch=0][
    ,mean(Covariance),by=Country]
   Country        V1
1:       1 0.3666667
2:       2 0.2010000

由于未将非对角线加倍,这与所需的结果不匹配。但希望这足以证明问题的错误消息中的特定建议,您可以从这里获取。或者使用matrix而不是data.table用于协方差类型的工作。

于 2013-08-07T14:13:04.503 回答