R中的大矩阵:暂不支持长向量。

21

我正在64位Ubuntu环境下运行64位R 3.1,拥有400GB的内存。当我处理大型矩阵时,遇到了奇怪的限制。

我有一个名为A的数值矩阵,它有4000行和950,000列。当我尝试访问其中任何一个元素时,会收到以下错误:

Error: long vectors not supported yet: subset.c:733

虽然我的矩阵是通过scan读取的,但你可以使用以下代码进行复制

test <- matrix(1,4000,900000) #no error
test[1,1] #error

我的谷歌搜索显示,在 R 3.0 之前,出现过这种常见的错误信息,其中向量的大小限制为2^31-1。但是,在我的环境中并非如此。

对于这种矩阵,我是否不应该使用本地矩阵类型?


2
有一些支持矩阵和数组,每个维度小于2^31但元素总数超过该值。请注意错误消息中的“some”和“yet”单词。 - Roland
3
在控制台提示符下输入 news() 并搜索 "LONG VECTORS",然后开始阅读。 - IRTFM
1
请查看ffbigmemory软件包。 - Barranka
@AndreyShabalin ...这里是标头中设置 LENGTHXLENGTH 差异的部分,链接在这里 - joran
这个错误在Linux上的R 3.4.3中不会发生。 - Ista
显示剩余5条评论
4个回答

21

矩阵就是一个带有维度属性的原子向量,这使得R可以把它作为矩阵进行访问。你的矩阵是长度为 4000*9000000 的向量,它包含了 3.6e+10 个元素(最大整数值约为 2.147e+9)。对于原子向量,支持子集操作(即访问超出 2.147e+9 限制的元素)。只需将您的矩阵视为长向量。

如果我们记住默认情况下R按列填充矩阵,那么如果我们想检索例如 test[ 2701 , 850000 ] 处的值,我们可以通过以下方式访问:

i <- ( 2701 - 1 ) * 850000 + 2701 
test[i]
#[1] 1

请注意这确实是长向量子集,因为:

2701L * 850000L
#[1] NA
#Warning message:
#In 2701L * 850000L : NAs produced by integer overflow

感谢您的出色回答。您能帮我理解一下您的第二个陈述吗?2701L * 850000L,为什么会产生NA,而2701*850000却不会呢?我原本以为通过指定L,它会将其存储为长整型并使其能够处理如此大的数字。 - The_Anomaly
因为 L 明确指定了整数类型。class(2701)"numeric"(850000 同理)。(我认为)R 没有原生长整型可供终端用户使用(参见 ?integer)。(不知道/记得)为什么 L 是整数代码,可能需要查看 R 语言手册? - Ben Bolker
1
感谢您的评论@BenBolker。对于其他可能正在阅读的人,numeric和double是相同的。因此,当谈论“长向量”时,实际上只是指“长度较长的向量”,而不是由长整数索引的向量,因为在R中不存在长整数。因此,当Simon写下2701L * 850000L导致NA时,这是因为我们强制使用了Integer类型,其限制为2.147e9。没有L,我们使用numeric(即double,具有更大的范围)。因此,L与C的long int无关 :) - The_Anomaly
1
@The_Anomaly 当C语言中的long int类型被引入时,它传统上是32位的(而int类型是16位的)。R已经存在一段时间了,所以我不同意你的观点,并推测(Ripley教授也同意)它是long int的简写。事实上,我写了一个关于这个问题的问答 - Simon O'Hanlon
那会有很多意义--感谢你的历史介绍,Simon。 - The_Anomaly
不,这个解决方案是错误的。例如,当 z = matrix(1:9, 3, 3)z[2, 3] # 8 时,会发生 z[ (2 - 1) * 3 + 2 ] # 5。正确的写法应该是:z[ (2) * 3 + 2 ] # 8 - Stingery

3

另一种快速解决方案是先获取矩阵的行,然后获取列(现在是结果向量的第i个元素)。例如...

test <- matrix(1,4000,900000) #no error 
test[1,1] #error
test[1, ][1] # no error

当然,这会产生一些开销,因为整行首先要复制/访问,但它更容易阅读。首先提取列再提取行也可以这样做。

0

TL;DR - 尝试从代码块头的花括号中删除 cache=TRUE 参数。

对于包含1,720,238个观测和302个变量的数据框,我遇到了这个错误,该值低于@Simon提到的阈值(1,720,238*302 = 5.2e+8 < 2.147e+9)

@subhash的回答给了我一个提示,让我尝试完全删除cache参数,这样就解决了我的错误。


-3

载入库(knitr)

knitr::option$set(cache = TRUE, warning = FALSE,message = FALSE, cache.lazy = FALSE)


2
什么?这是什么样的回答? - raygozag
2
这实际上帮了我很多,因为我的长向量问题源于 Rmd 缓存机制,请参见 https://bookdown.org/yihui/rmarkdown-cookbook/cache-lazy.html 但是答案与上下文无关,我同意! - Jan Netík
更多信息,请参考这个答案的逻辑可能来自这里:https://dev59.com/IlkS5IYBdhLWcg3w05eT#41004082 - arielhasidim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接