我在 R 给出Can not allocate vector of size XX Gb
错误消息时遇到了内存问题。我有一堆 netcdf 格式的每日文件(12784 天),在 1305x378(经纬度)网格中给出海面温度。这每天给出 493290 点,当移除 NA(超过陆地点)时减少到大约 245000。
我的最终目标是为每日文件中的 245000 个点中的任何一个构建一个时间序列,并找到每个点的时间趋势。我的想法是构建一个大数据框,每行一个点,每列一天(2450000x12784),这样我就可以将趋势计算应用于任何点。但是随后,在构建这样的数据框时,正如预期的那样,出现了内存问题。
首先,我尝试了一个我以前用来读取数据并通过读取 nc 文件然后融合数据来提取三列(lon-lat-sst)数据帧的脚本。当尝试一小部分天时,这会导致计算时间过长,并导致内存问题。然后我尝试将日常文件分成纵向切片;这避免了内存问题,但 csv 输出文件太大并且该过程非常耗时。
我尝试过的另一种策略没有成功,它是顺序读取所有 nc 文件,然后提取每个点的所有每日值并找到趋势。然后我只需要保存一个 245000 点数据框。但我认为这将是耗时的,而不是正确的 R 方式。
我一直在阅读big.memory
并ff
尝试声明 big.matrix 或 3D 数组(1305 x 378 x 12784)的包,但现在还没有成功。
面对这个问题的适当策略是什么?
- 提取单点时间序列以计算单个趋势并填充较小的数据框
- 对切片中的每日文件进行子集以避免内存问题,但以大量数据帧/文件结尾
- 尝试用 bigmemory 或 ff 包解决内存问题
在此先感谢您的帮助
编辑 1 添加代码以填充矩阵
library(stringr)
library(ncdf4)
library(reshape2)
library(dplyr)
# paths
ruta_datos<-"/home/meteo/PROJECTES/VERSUS/CMEMS/DATA/SST/"
ruta_treball<-"/home/meteo/PROJECTES/VERSUS/CMEMS/TREBALL/"
setwd(ruta_treball)
sst_data_full <- function(inputfile) {
sstFile <- nc_open(inputfile)
sst_read <- list()
sst_read$lon <- ncvar_get(sstFile, "lon")
sst_read$lats <- ncvar_get(sstFile, "lat")
sst_read$sst <- ncvar_get(sstFile, "analysed_sst")
nc_close(sstFile)
sst_read
}
melt_sst <- function(L) {
dimnames(L$sst) <- list(lon = L$lon, lat = L$lats)
sst_read <- melt(L$sst, value.name = "sst")
}
# One month list file: This ends with a df of 245855 rows x 33 columns
files <- list.files(path = ruta_datos, pattern = "SST-CMEMS-198201")
sst.out=data.frame()
for (i in 1:length(files) ) {
sst<-sst_data_full(paste0(ruta_datos,files[i],sep=""))
msst <- melt_sst(sst)
msst<-subset(msst, !is.na(msst$sst))
if ( i == 1 ) {
sst.out<-msst
} else {
sst.out<-cbind(sst.out,msst$sst)
}
}
编辑 2 在先前(较小)数据帧中用于计算时间趋势的代码。原始数据是一个时间序列矩阵,每一列都是一个序列。
library(forecast)
data<-read.csv(....)
for (i in 2:length(data)){
var<-paste("V",i,sep="")
ff<-data$fecha
valor<-data[,i]
datos2<-as.data.frame(cbind(data$fecha,valor))
datos.ts<-ts(datos2$valor, frequency = 365)
datos.stl <- stl(datos.ts,s.window = 365)
datos.tslm<-tslm(datos.ts ~ trend)
summary(datos.tslm)
output[i-1]<-datos.tslm$coefficients[2]
}
fecha 是日期变量名
编辑 2 来自 F. Privé 答案的工作代码
library(bigmemory)
tmp <- sst_data_full(paste0(ruta_datos,files[1],sep=""))
library(bigstatsr)
mat <- FBM(length(tmp$sst), length(files),backingfile = "/home/meteo/PROJECTES/VERSUS/CMEMS/TREBALL" )
for (i in seq_along(files)) {
mat[, i] <- sst_data_full(paste0(ruta_datos,files[i],sep=""))$sst
}
使用此代码创建了一个大矩阵
dim(mat)
[1] 493290 12783
mat[1,1]
[1] 293.05
mat[1,1:10]
[1] 293.05 293.06 292.98 292.96 292.96 293.00 292.97 292.99 292.89 292.97
ncol(mat)
[1] 12783
nrow(mat)
[1] 493290