我试图用 R 开发一个程序来估计与 Rcpp 的 Spearman 相关性。我做到了,但它只适用于范围小于 45 00 - 50 000 个向量的矩阵。我不知道为什么,但它只适用于那个维度。我想这种类型的信息是有限制的,也许如果我像 data.frame 一样工作?如果有人给我见解,我将不胜感激。
在这里我发布我的代码。我一直试图限制我称之为“分母”的最大整数,它超过了它。也许你可以帮助我。
cppFunction('double spearman(NumericMatrix x){
int nrow = x.nrow(), ncol = x.ncol();
int nrow1 = nrow - 1;
double out = 0;
double cont = 0;
double cont1 = 0;
double r = 0;
int denominador = ncol*(pow(ncol,2.0)-1)
for(int i = 0; i < nrow1; i++){
#Here i use every combination of vectors starting with the first one, and so on
for(int j = i +1; j < nrow; j++){
cont1 = 0;
for(int t = 0; t < ncol; t++){
cont = pow(x(i,t)-x(j,t), 2.0);
cont1 += cont;
}
#Here i begin to store the mean correlation, in order to a final mean of all the possible correlations
r = 2*(1-6*(cont1/denominador))/(nrow*nrow1);
out += r;
}
}
return out;
}')
Run Code Online (Sandbox Code Playgroud)
在我们开始之前,我假设:
R > 3.0.0
Rcpp > 0.12.0
int,并size_t与R_xlen_t和R_xlength。有关更多详细信息,请参阅发布帖子...NumericMatrix我认为您可能会遇到内存分配问题...
由于以下适用于我的 32GB 机器:
Rcpp::cppFunction("NumericMatrix make_matrix(){
NumericMatrix m(50000, 50000);
return m;
}")
m = make_matrix()
object.size(m)
## 20000000200 bytes # about 20.0000002 gb
Run Code Online (Sandbox Code Playgroud)
跑步:
# Creates an 18.6gb matrix!!!
m = matrix(0, ncol = 50000, nrow = 50000)
Rcpp::cppFunction("void get_length(NumericMatrix m){
Rcout << m.nrow() << ' ' << m.ncol();
}")
get_length(m)
## 50000 50000
object.size(m)
## 20000000200 bytes # about 20.0000002 gb
Run Code Online (Sandbox Code Playgroud)
理论上,您受到矩阵中元素总数小于 (2^31 - 1)^2 = 4,611,686,014,132,420,609 的限制:
数组(包括矩阵)可以基于长向量,前提是它们的每个维度最多为 2^31 - 1:因此没有一维长数组。
见龙矢量
现在,拟合成一个矩阵:
m = matrix(nrow=2^31, ncol=1)
Run Code Online (Sandbox Code Playgroud)
矩阵错误(nrow = 2^31,ncol = 1):无效的“nrow”值(太大或不适用)
另外:警告消息:在矩阵(nrow = 2^31, ncol = 1) 中:
强制引入整数范围的 NA
极限都[R和RCPP遵守关于列/行是:
.Machine$integer.max
## 2147483647
Run Code Online (Sandbox Code Playgroud)
请注意,通过 1 个数字,我们有:
2^31 = 2,147,483,648 > 2,147,483,647 = .Machine$integer.max
但是,与纯 原子向量相关的限制为 2^52(即使它应该在 2 ^ 64 - 1 的范围内)。因此,我们有以下示例,它说明了通过连接两个 2^31 + 2^31 向量来访问 2^32 的能力:
v = numeric(2^31)
length(v)
## [1] 2147483648
object.size(v)
## 17179869224 bytes # about 17.179869224 gb
v2 = c(v,v)
length(v2)
## 4294967296
object.size(v2)
## 34359738408 bytes # about 34.359738408 gb
Run Code Online (Sandbox Code Playgroud)
bigmemory通过Rcpp更简洁地重复:
向量中可以有超过 2^31-1 个元素。
矩阵是具有dim属性的向量。
矩阵中可以有超过 2^31-1 个元素(即ntimes k)
您的行和列索引仍限制为 2^31。
大向量的例子:
R> n <- .Machine$integer.max + 100
R> tmpVec <- 1:n
R> length(tmpVec)
[1] 2147483747
R> newVec <- sqrt(tmpVec)
R>
Run Code Online (Sandbox Code Playgroud)