我遇到內存問題,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
怎麼樣如果你把所有的數據放在適當的數據庫中並從那裏查詢? –
這可能會運行,但我只有基本的數據庫知識,我也有一個截止日期,如果可能,我更喜歡基於R的解決方案。謝謝。 – pacomet
這可以通過大小(1305x378)x 12784(磁盤上47GB)的'big.matrix'(bigmemory)或'FBM'(bigstatsr)來完成。你應該填寫一欄(每一天)。但是你感興趣的是每一行,然後你可以轉置它(例如'big_transpose'),然後在每列(每個點)上操作。 –