簡體   English   中英

嵌套用於R中的NetCDF的循環

[英]Nested for loops with NetCDFs in R

我非常感謝所有想幫助我解決我確實遇到的問題的人。 但提前:這是一個復雜的話題,我會盡力解釋我打算對我的代碼做些什么。 它與NetCDF文件中的氣候數據有關,其中包含1971年至2000年以及2071年至2100年時間的月度溫度(tas)和降水量(pr)數據。 440x400網格點(歐洲地圖)。 未來期間的nc文件包含1x1網格點(對於感興趣的城市)。 每個網格點具有360個溫度或降水值(取決於模型),在30年期間的每個月都有一個值。 換句話說:每個網格點都有360個點的分布。 現在,我想迭代計算單個城市網格點(2071-2100)的分布與每個歐洲(1971-2000)網格點的分布之間的統計差異。 我將獲得每個歐洲網格點的平均平均距離。 這個想法是在歐洲網格柵格中找到其溫度或降水分布與將來感興趣的城市的分布最相似的網格點。 我必須針對30種不同的氣候模型進行計算。

# List filenames of the directory

hist.files <- list.files("/historical", full.names = TRUE)
rcp.files <- list.files("/rcp", full.names = TRUE)

#Create array for desired ‘similarity indices’. One matrix per climate model run.

sim.array <- array(NA, dim = c(440,400,30))

#Looping through the models of the period 1971-2000. Some containing precipitation data others temperature (see if…else) 

for(k in 1:length(hist.files))   {
        hist.data <- nc_open(hist.files[k])   

   if(grepl("pr", hist.data$filename)){
    hist.tas <- ncvar_get(hist.data, "pr")
        }else{
    hist.tas <- ncvar_get(hist.data, "tas") 
    hist.tas <- kelvin.to.celsius(hist.tas, round=2)
   }

#Looping through the models of the 2071 to 2100 period (city). Some containing precipitation data others temperature (see if…else)

for(r in 1:length(rcp.files)) {
    rcp.data <- nc_open(rcp.files[r])
    if(grepl("pr", rcp.data$filename)){
    rcp.tas <- ncvar_get(rcp.data, "pr") 
        }else{
    rcp.tas <- ncvar_get(rcp.data, "tas")
    rcp.tas <- kelvin.to.celsius(rcp.tas, round=2)
        }

#This if statement because hist contains more models than rcp and I want to exclusively use the models contained in both of them.  

if(hist.data %in% rcp.data) {  

#Looping through the grid points of ‘hist’ model k. Lastly the function that calculates for each grid point of the model a difference value (always to the one grid point of ‘rcp’). My idea of the break statement was to loop nrow and ncol the same times, but I’m not sure if break does what I intended to.       

for(i in 1:nrow(hist.tas)) { 
       for(j in 1:ncol(hist.tas)) {
    sim.array[i,j,k] <- abs(sum(rcp.tas - hist.tas[i,j,])/360)
break
    }
  print(sim.array[i,j,k])
  }
 }
}   
}
sim.array[1,1,1]

好吧,我得到了一個充滿NA的數組。 沒有錯誤消息,但是出了點問題! 有人可以找到錯誤嗎? 感謝您的幫助。 提前非常感謝您!

更新:您的建議似乎是一個好的解決方案! 到現在為止,我還沒有時間應用它們,但是我稍后再做! 我一直在考慮矢量化,但是沒有設法從3維數組中制作出矢量,而最后沒有一個充滿不同矢量的混亂代碼……我都不知道如何刪除與hist和rcp不匹配的模型。 通過相交和%in%,我知道了不匹配文件的索引...但是,必須有比手動記錄所有這些索引來刪除更好的方法,不是嗎? 請查看一些歷史文件名:

> hist.files.tas <- list.files("/historical", full.names = TRUE, pattern = "tas")
> hist.files.tas
 [1] "/historical/tas_CNRM-CERFACS-CNRM-CM5_CLMcom-CCLM4-8-17_r1i1p1.nc"   
 [2] "/historical/tas_CNRM-CERFACS-CNRM-CM5_CNRM-ALADIN53_r1i1p1.nc"       
 [3] "/historical/tas_CNRM-CERFACS-CNRM-CM5_RMIB-UGent-ALARO-0_r1i1p1.nc"  
 [4] "/historical/tas_CNRM-CERFACS-CNRM-CM5_SMHI-RCA4_r1i1p1.nc"           
 [5] "/historical/tas_ICHEC-EC-EARTH_CLMcom-CCLM4-8-17_r12i1p1.nc"         
 [6] "/historical/tas_ICHEC-EC-EARTH_DMI-HIRHAM5_r3i1p1.nc"                
 [7] "/historical/tas_ICHEC-EC-EARTH_KNMI-RACMO22E_r12i1p1.nc"             
 [8] "/historical/tas_ICHEC-EC-EARTH_KNMI-RACMO22E_r1i1p1.nc"              
 [9] "/historical/tas_ICHEC-EC-EARTH_SMHI-RCA4_r12i1p1.nc"                 
[10] "/historical/tas_IPSL-IPSL-CM5A-MR_INERIS-WRF331F_r1i1p1.nc"          
[11] "/historical/tas_IPSL-IPSL-CM5A-MR_SMHI-RCA4_r1i1p1.nc"               
[12] "/historical/tas_MOHC-HadGEM2-ES_CLMcom-CCLM4-8-17_r1i1p1.nc"         
[13] "/historical/tas_MOHC-HadGEM2-ES_KNMI-RACMO22E_r1i1p1.nc"             
[14] "/historical/tas_MOHC-HadGEM2-ES_SMHI-RCA4_r1i1p1.nc"   

還有更多具有tasmax和tasmin變量的模型。 hist總共有71個文件,而rcp只有30個。您能給我一個例子,說明如何編寫一個自動代碼刪除不匹配的hist文件嗎? 非常感謝!

在我看來,以下內容毫無意義,並且始終為假:

if (hist.data %in% rcp.data)

所以sim_array什么也沒有發生

我將從做這樣的事情開始:

hist.files.pr <- list.files("/historical", full.names = TRUE, pattern="pr")
hist.files.tas <- list.files("/historical", full.names = TRUE, pattern="tas")
rcp.files.pr <- list.files("/rcp", full.names = TRUE, pattern="pr")
rcp.files.tas <- list.files("/rcp", full.names = TRUE, pattern="tas")

此時,對於不在“ rcp”中的模型,您可以從“歷史”中刪除文件

hist.files.tas <- c( "/historical/tas_CNRM-CERFACS-CNRM-CM5_CLMcom-CCLM4-8-17_r1i1p1.nc", "/historical/tas_CNRM-CERFACS-CNRM-CM5_CNRM-ALADIN53_r1i1p1.nc", "/historical/tas_CNRM-CERFACS-CNRM-CM5_RMIB-UGent-ALARO-0_r1i1p1.nc", "/historical/tas_CNRM-CERFACS-CNRM-CM5_SMHI-RCA4_r1i1p1.nc", "/historical/tas_ICHEC-EC-EARTH_CLMcom-CCLM4-8-17_r12i1p1.nc", "/historical/tas_ICHEC-EC-EARTH_DMI-HIRHAM5_r3i1p1.nc", "/historical/tas_ICHEC-EC-EARTH_KNMI-RACMO22E_r12i1p1.nc", "/historical/tas_ICHEC-EC-EARTH_KNMI-RACMO22E_r1i1p1.nc", "/historical/tas_ICHEC-EC-EARTH_SMHI-RCA4_r12i1p1.nc", "/historical/tas_IPSL-IPSL-CM5A-MR_INERIS-WRF331F_r1i1p1.nc", "/historical/tas_IPSL-IPSL-CM5A-MR_SMHI-RCA4_r1i1p1.nc", "/historical/tas_MOHC-HadGEM2-ES_CLMcom-CCLM4-8-17_r1i1p1.nc", "/historical/tas_MOHC-HadGEM2-ES_KNMI-RACMO22E_r1i1p1.nc", "/historical/tas_MOHC-HadGEM2-ES_SMHI-RCA4_r1i1p1.nc")

# in this example, fut files is a subset of hist files; that should be OK if their filename structure is the same

rcp.files.tas <- hist.files.tas[1:7]

getModels <- function(ff) {
    base <- basename(ff)
    s <- strsplit(base, "_")
    sapply(s, function(i) i[[2]])
}

getHistModels <- function(hist, fut) {
    h <- getModels(hist)
    uh <- unique(h)
    uf <- unique(getModels(fut))
    uhf <- uh[uh %in% uf]
    hist[h %in% uhf]
}


hist.files.tas.selected <- getHistModels(hist.files.tas, rcp.files.tas)
# hist.files.pr.selected <- getHistModels(hist.files.pr, rcp.files.pr)

可以通過執行以下操作避免雙循環(k,r):

library(raster)
his.pr <- values(stack(hist.files.pr.selected, var="pr")))
his.tas <- values(stack(hist.files.tas.selected, var="tas"))
rcp.pr <- values(stack(hist.files.pr, var="pr"))
rcp.tas <- values(stack(hist.files.tas, var="tas"))

並且也可以避免在行和列上的(i,j)循環。 R被向量化。 也就是說,您可以執行(1:10) - 2

無論哪種方式,使用所有這些嵌套循環都很難閱讀代碼。 如果您確實需要它們,則最好調用函數。 要獲得更多幫助,請提供一些示例數據而不是我們沒有的文件,或者提供一些文件。

因為在我的數據集中,除了“ tas”和“ pr”之外,實際上還有另外兩個變量“ tasmax”和“ tasmin”,Robert的方法對我的案例來說要寫得多。 因此,我嘗試了另一種方法,終於解決了,盡管它沒有單獨列出每個變量的文件(缺點是,是的!)。

列出和匹配歷史文件和rcp文件:

要匹配文件,我需要不帶目錄的文件的純名稱,否則,((hist%in%rcp)始終為FALSE(如Robert所示)。

hist <-list.files(“ / historical”)rcp <-list.files(“ / rcp26”)

no.match.h <-which(!hist%in%rcp)no.match.r <-which(!rcp%in%hist)

因為我需要nc_open,包括目錄的文件名,所以我必須創建一個相應的文件列表並減去不匹配的文件

hist.files <-list.files(“ / data / scratch / lorchdav / cordex_eur / monmean / historical”,full.names = TRUE)rcp.files <-list.files(“ / data / scratch / lorchdav / cordex_ber_mean / rcp26 “,full.names = TRUE)

hist.files.cl <-hist.files [-no.match.h] hist.files.cl

rcp.files.cl <-rcp.files [-no.match.r] rcp.files.cl

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM