2017-09-22 113 views
1

我遇到內存問題,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.memoryff包,試圖聲明big.matrix或3D數組(1305 x 378 x 12784),但現在還沒有成功。

面對問題的適當策略是什麼?

  1. 提取單點時間序列來計算個人的發展趨勢,並形成一個較小的數據幀
  2. 子集日常文件切片,以避免內存不足的問題,但有很多dataframes結束/文件
  3. 嘗試解決內存事先與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 
+5

怎麼樣如果你把所有的數據放在適當的數據庫中並從那裏查詢? –

+0

這可能會運行,但我只有基本的數據庫知識,我也有一個截止日期,如果可能,我更喜歡基於R的解決方案。謝謝。 – pacomet

+0

這可以通過大小(1305x378)x 12784(磁盤上47GB)的'big.matrix'(bigmemory)或'FBM'(bigstatsr)來完成。你應該填寫一欄(每一天)。但是你感興趣的是每一行,然後你可以轉置它(例如'big_transpose'),然後在每列(每個點)上操作。 –

回答

1

所以,在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 
} 
+0

看來它在第一個月裏工作正常,創建一個493290行和31列的矩陣,所有點/行爲一個月/列。要嘗試全套,35年。 – pacomet

+0

Hi @F.Privé矩陣有一個問題,我認爲後臺文件位於我的系統的/ tmp中,但沒有足夠的可用空間。可以將它移動到有足夠磁盤空間的/ home嗎? – pacomet

+0

@pacomet Yeap,有一個參數。 –