R-在数组的每个元素上并行应用函数

时间:2019-07-02 03:44:44

标签: arrays r parallel-processing multicore

我将最大和最小温度和降水的测量结果按大小数组进行组织 (100x96x50769),其中i和j是与坐标相关联的网格单元,z表示一段时间内的测量次数。

从概念上讲,它看起来像这样:

enter image description here

我正在使用climdex.pcic包来计算极端天气事件的索引。给定最大,最小温度和降水的时间序列,climdexInput.raw函数将返回一个climdexIput对象,该对象可用于确定多个指标:霜冻天数,夏季天数,连续的干旱天数等

该函数的调用非常简单:

ci <- climdexInput.raw(tmax=x, tmin=y, prec=z,
                       t, t, t, base.range=c(1961,1990))

其中x是最高温度的向量,y是最低温度的向量,z是降水的向量,t是具有测量x,y和z的日期的向量。

我想做的是为数组中每个元素(即上图中的每个网格单元)提取时间序列,并使用它来运行climdexInput.raw函数。

由于真实数据中的大量元素,我想在我的4核Linux服务器上并行运行此任务。但是,我没有R中并行化的经验。

这是我的程序的一个示例(故意减小尺寸以使计算机上的执行速度更快):

library(climdex.pcic)

# Create some dates
t <- seq(as.Date('2000-01-01'), as.Date('2010-12-31'), 'day')

# Parse the dates into PCICt
t <- as.PCICt(strftime(t), cal='gregorian')

# Create some dummy weather data, with dimensions `# of lat`, `# of lon` and `# of timesteps`
nc.min <- array(runif(10*9*4018, min=0, max=15), c(10, 9, 4018))
nc.max <- array(runif(10*9*4018, min=25, max=40), c(10, 9, 4018))
nc.prc <- array(runif(10*9*4018, min=0, max=25), c(10, 9, 4018))

# Create "ci" object
ci <- climdexInput.raw(tmax=nc.max[1,1,], tmin=nc.min[1,1,], prec=nc.prc[1,1,],
                       t, t, t, base.range=c(2000,2005))

# Once you have “ci”, you can compute any of the indices provided by the climdex.pcic package.
# The example below is for cumulative # of dry days per year:
cdd <- climdex.cdd(ci, spells.can.span.years = TRUE) 

现在,请注意,在上面的示例中,我仅使用数组的第一个元素([1,1,])作为climdexInput.raw函数中的示例。

如何利用循环处理对所有元素进行相同的处理,可能是通过遍历数组的维度ij来实现的?

1 个答案:

答案 0 :(得分:1)

您可以使用foreach来做到这一点:

library(doParallel)
registerDoParallel(cl <- makeCluster(3))
res <- foreach(j = seq_len(ncol(nc.min))) %:% 
  foreach(i = seq_len(nrow(nc.min))) %dopar% {
    ci <- climdex.pcic::climdexInput.raw(
      tmax=nc.max[i,j,], 
      tmin=nc.min[i,j,],
      prec=nc.prc[i,j,],
      t, t, t, 
      base.range=c(2000,2005)
    )
  }
stopCluster(cl)

请参阅我的使用foreach的并行性指南:https://privefl.github.io/blog/a-guide-to-parallelism-in-r/

然后,要计算索引,只需使用climdex.cdd(res[[1]][[1]], spells.can.span.years = TRUE)(首先使用j,然后使用i)。