R + ggplot2 - 无法分配大小为128.0 Mb的向量

3

我有一个4.5MB(9,223,136行)的文件,其中包含以下信息:

0       0
0.0147938       3.67598e-07
0.0226194       7.35196e-07
0.0283794       1.10279e-06
0.033576        1.47039e-06
0.0383903       1.83799e-06
0.0424806       2.20559e-06
0.0465545       2.57319e-06
0.0499759       2.94079e-06

每一列都代表了一个从0到100的值,表示一个百分比。我的目标是在ggplot2中绘制一个图形,以查看它们之间的百分比(例如,在column1中使用20%时,在column2上实现了什么百分比)。这是我的R脚本:

library(ggplot2)
dataset=read.table("~/R/datasets/cumul.txt.gz")
p <- ggplot(dataset,aes(V2,V1))
p <- p + geom_line()
p <- p + scale_x_continuous(formatter="percent") + scale_y_continuous(formatter="percent")
p <- p + theme_bw()
ggsave("~/R/grafs/cumul.png")

我有一个问题,每次运行这个程序时,R都会耗尽内存,显示错误信息:"Cannot allocate vector of size 128.0 Mb"。我的机器是Linux系统,使用的是32位的R,而且还有4GB的空闲内存。

我考虑了一种解决方法,即通过舍入减少这些值的精度,并消除数据集中的重复行,以便在数据集中拥有更少的行数。您能否给我一些建议?


1
你的工作区里还有其他对象吗?当我遇到这种情况时,通常会保存我需要的对象,然后重新启动一个干净的工作区。如果你删除不需要的对象,调用gc()也可能会有所帮助。 - richiemorrisroe
@richie 我启动了一个干净的 R 会话,只调用了这个脚本: /usr/bin/R CMD BATCH --vanilla --no-timing ~/scripts/R/grafs/cumul.R ~/R/scripts_output/cumul.txt - Barata
这个脚本只创建上面的例子还是会创建更多的对象? - richiemorrisroe
@richiemorrisroe 我尝试在8GB RAM、64位Win上运行它(使用虚拟数据和干净的工作空间)。当我终止它时,进程已经达到了6GB。因此,唯一的方法就是限制数据的大小。 - Marek
1个回答

12

你确定你有一份4.5MB大小的文件里面有900万行代码吗(编辑:也许你的文件是4.5GB?)?它一定被压缩得很厉害——当我创建一个只有这个文件十分之一大小的文件时,它已经有115MB了...

n <- 9e5
set.seed(1001)
z <- rnorm(9e5)
z <- cumsum(z)/sum(z)
d <- data.frame(V1=seq(0,1,length=n),V2=z)
ff <- gzfile("lgfile2.gz", "w")
write.table(d,row.names=FALSE,col.names=FALSE,file=ff)
close(ff)
file.info("lgfile2.gz")["size"]

从您提供的信息很难确定数据集中有哪些类型的“重复行”... unique(dataset) 将提取唯一的行,但可能没有用处。我会通过简单地将数据集稀疏化100或1000倍来开始处理:

smdata <- dataset[seq(1,nrow(dataset),by=1000),]

试着这样做并观察结果(编辑:忘了一个逗号!)

对于大型数据集的图形表示通常是一项挑战。一般来说,你可以更好地做到:

  • 在绘制图形之前对数据进行某种汇总
  • 使用特定的图形类型(密度图、轮廓图、六边形分箱),以减少数据量
  • 使用基本绘图,它采用“画完即忘”的模式(除非启用了图形记录,例如在Windows中),而不是lattice/ggplot/grid绘图,后者保存完整的图形对象然后再渲染
  • 使用栅格或位图图形(PNG等),它仅记录图像中每个像素的状态,而不是矢量图形,后者保存所有对象,无论它们是否重叠

你的前两点是最重要的(并且是等价的)- 如果你适当地总结数据,基础和网格的绘制速度就不重要了。 - hadley
1
@hadley:说得好。从初学者的角度来看,使用黑盒机器一步完成数据汇总和绘图(适当使用sum_stat()plot(density(x))等)可能与自己进行汇总有所不同。我同意找到汇总数据的方法更加优雅且长远来看更有效率,尽管在短期内进行调试时考虑#3和#4也是有用的。 - Ben Bolker

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