由于数据集较大,导致PC中的PCoA出错

时间:2013-05-14 09:42:16

标签: r memory statistics large-files

对于我的工作项目,我必须执行PCoA(主坐标分析,即多维缩放)。 但是,当使用R执行此分析时,我遇到了一些问题。

函数cmdscale只接受矩阵或dist作为输入,dist函数给出错误:

Error: cannot allocate vector of size 4.2 Gb
In addition: Warning messages:
1: In dist(mydata[c(3, 4)], method = "euclidian", diag = FALSE, upper = FALSE) :
  Reached total allocation of 4020Mb: see help(memory.size)
2: In dist(mydata[c(3, 4)], method = "euclidian", diag = FALSE, upper = FALSE) :
  Reached total allocation of 4020Mb: see help(memory.size)
3: In dist(mydata[c(3, 4)], method = "euclidian", diag = FALSE, upper = FALSE) :
  Reached total allocation of 4020Mb: see help(memory.size)
4: In dist(mydata[c(3, 4)], method = "euclidian", diag = FALSE, upper = FALSE) :
  Reached total allocation of 4020Mb: see help(memory.size)

当我使用矩阵时,它会将输入更改为:

     [,1]         
[1,] Integer,33741
[2,] Integer,33741

数据集的内容无法在线发布,但我可以为您提供尺寸: 数据集长33741行,宽11列,第一列是ID,另外10个值需要用于PCoA。

正如您在错误中看到的那样,我只使用了2列,并且我已经收到了内存错误。

现在我的问题:
是否有可能以这样的方式操纵数据,即我可以使用dist函数的内存限制来管理? 我对矩阵函数做错了什么,它将向量更改为2列2行输出?

我尝试过: 清除垃圾收集,重新启动GUI,重新启动系统。

系统: Windows 7 x64 i7 920qm 1.8ghz 4GB DDR3内存

使用的代码:

mydata <- read.table(file, header=TRUE)

mydist <- dist(mydata[c(3,4)], method="euclidian", diag=FALSE, upper=FALSE)
mymatrix <- matrix(mydata[c(3,4)], byrow=FALSE)
mymatrix <- matrix(cbind(mydata[c(3,4)]))

mycmdscale <- cmdscale(mydist, k=2, eig=FALSE, add=FALSE, x.ret=FALSE)
mycmdscale <- cmdscale(mymatrix, k=2, eig=FALSE, add=FALSE, x.ret=FALSE)

plot(mycmdscale)

当然我没有按此顺序运行代码,但此代码包含我尝试加载数据的方法。

提前感谢您的回复。

2 个答案:

答案 0 :(得分:0)

在R中执行此操作的内存太少,R将内存中的所有对象都保存在内。我可能没有完全正确的计算(我忘记了R的对象的大小)但只是为了保存相差矩阵,你需要~9GB的RAM。

> print(object.size(matrix(0, ncol = 34000, nrow = 34000)), units = "Gb")
8.6 Gb

dist将在内部表示中减少,因为它实际上只存储0.5 * (nr * (nr - 1))个双精度数(nr是输入数据中的行数):

> print(object.size(numeric(length = 0.5 * 34000 * 33999)), units = "Gb")
4.3 Gb

[这可能是你看到的错误来自哪里]

实际上,一旦你计算了相差矩阵,就需要超过20-30GB的RAM来做任何有用的事情。即使你可以计算它们,PCoA解决方案的特征向量也只需要9Gb的RAM。

所以一个更相关的问题是;你希望用c做什么? 34000个样本/观察结果?

要从mydata[3:4]获取矩阵,您可以使用

as.matrix(mydata[3:4])

或者,如果您有因素并希望保留其数字解释

data.matrix(mydata[3:4])

答案 1 :(得分:0)

我知道这已经过时了,但我还是想知道我得到的东西......

我有点意外@Gavin Simpson没有提到计算欧几里德距离矩阵的主坐标分析与主成分分析相同(至少对两者都使用scale = 1)。

这是根据p。 143 Bor Bor,D.,Gillet,F。,&amp; Legendre,P。(2011)。第五章无约束的圣职任命(第115-151页)。纽约,纽约:斯普林格纽约。 DOI:10.1007 / 978-1-4419-7976-6

我可以在我当前的本地机器上运行这个 系统:Windows 7 x64 i5-2500 3.3ghz 8GB RAM

library(vegan) # to perform PCA and associated operations 
library(ggplot2) # plotting (not necessary, but nice)
library(grid) # arrow()

#make a big test set like OP's
test<-data.frame(id=seq(34000), var1=rnorm(34000), var2=rnorm(34000),
                 var3=rnorm(34000),var4=rnorm(34000),var5=rnorm(34000),
                 var6=rnorm(34000),var7=rnorm(34000),var8=rnorm(34000),
                 var9=rnorm(34000),var10=rnorm(34000))
#calculate PCA
test.pca<-rda(test, scale=TRUE)

#calculate percent variation on each axis
test.pca.percExp<-round(eigenvals(test.pca)/sum(eigenvals(test.pca))*100, 2)

#extract scores for plotting
test.pca.sc<-scores(test.pca, choices=c(1,2), 
                           display=c("sites", "species"), scaling=1)

test.pca.site<-data.frame(test.pca.sc$sites)
test.pca.spe<-data.frame(test.pca.sc$species)
test.pca.spe$VAR<-rownames(test.pca.spe)

#make the plot
test.pca.p<-ggplot(test.pca.site, aes(PC1, PC2)) + 
  xlab(sprintf("PC1 %s%s", test.pca.percExp[1], "%")) + 
  ylab(sprintf("PC2 %s%s", test.pca.percExp[2], "%")) 

#add points and biplot arrows to plot
test.pca.p + 
  geom_point() +
  geom_segment(data = test.pca.spe,
               aes(x = 0, xend = PC1, y = 0, yend = PC2),
               arrow = arrow(length = unit(0.25, "cm")), colour = "grey") +
  geom_text(data=test.pca.spe,
            aes(x=PC1,y=PC2,label=VAR),
            size=3, position=position_jitter(width=-2, height=0.1))+
  guides(color = guide_legend(title = "Var"))

enter image description here

#hard to see the points with arrows, so plot without the arrows
test.pca.p + 
  geom_point()

enter image description here

我偶然发现了这个问题,因为我对曼哈顿距离矩阵存在同样的问题,我的回答无济于事(据我所知,可能有一种方法可以在PCA之前转换数据,这会给出相同的结果..)。这个答案基本上会给出我认为OP正在寻找的结果。希望这也有助于其他人...