处理R中的大数据集
我遇到内存问题,R给出Can not allocate vector of size XX Gb
错误消息。我有一堆日常文件(12784天),以netcdf格式给出1305x378(经纬度)网格的海面温度。这样每天就可以得到493290分,在移除新地区(陆地点)时减少到约245000。处理R中的大数据集
我的最终目标是从日常文件中为任何245000点建立一个时间序列,并找出每个点的时间趋势。我的想法是建立一个每行一个点和一个一天一列(2450000x12784)的大数据框,这样我就可以将趋势计算应用于任何点。但是,随着构建这样的数据框架,出现了内存问题,如预期的那样。
首先我试了一个我以前用来读取数据的脚本,通过读取nc文件然后融化数据来提取三列(lon-lat-sst)数据帧。这会导致在尝试一小段时间和内存问题时计算时间过长。然后我试图将每日文件分成纵向切片;这避免了内存问题,但csv输出文件太大,并且该过程非常耗时。
另一个策略,我试过没有成功的一刻,它已经顺序读取所有的NC文件,然后提取每个点的所有日常值,并找到趋势。然后我只需要保存一个245000点的数据帧。但我认为这会很耗时,而不是适当的R方式。
我一直在阅读大约big.memory
和ff
包,试图声明big.matrix或3D数组(1305 x 378 x 12784),但现在还没有成功。
面对问题的适当策略是什么?
- 提取单点时间序列来计算个人的发展趋势,并形成一个较小的数据帧
- 子集日常文件切片,以避免内存不足的问题,但有很多dataframes结束/文件
- 尝试解决内存事先与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]
}
日期星是日期变量名
编辑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
所以,在Filebacked大矩阵(FBM)你读出的数据,你可以做
files <- list.files(path = "SST-CMEMS", pattern = "SST-CMEMS-198201*",
full.names = TRUE)
tmp <- sst_data_full(files[1])
library(bigstatsr)
mat <- FBM(length(tmp$sst), length(files))
for (i in seq_along(files)) {
mat[, i] <- sst_data_full(files[i])$sst
}
怎么样如果你把所有的数据放在适当的数据库中并从那里查询? –
这可能会运行,但我只有基本的数据库知识,我也有一个截止日期,如果可能,我更喜欢基于R的解决方案。谢谢。 – pacomet
这可以通过大小(1305x378)x 12784(磁盘上47GB)的'big.matrix'(bigmemory)或'FBM'(bigstatsr)来完成。你应该填写一栏(每一天)。但是你感兴趣的是每一行,然后你可以转置它(例如'big_transpose'),然后在每列(每个点)上操作。 –