R:从多维深度水平阵列获得特定深度

时间:2016-09-28 06:27:23

标签: r multidimensional-array interpolation netcdf r-raster

我需要根据HYCOM数据计算25度等温线深度,该数据在选定区域内具有33个深度海洋温度。

我使用以下链接从netcdf子集工具下载数据

http://ncss.hycom.org/thredds/ncss/GLBa0.08/latest/temp?var=temperature&north=25&west=74.1199&east=434.1199&south=-15&horizStride=1&time_start=2016-09-27T00%3A00%3A00Z&time_end=2016-09-27T23%3A59%3A00Z&timeStride=1&vertCoord=&accept=netcdf4

以netcdf 4格式设置并由ncdf4库导入到R的数据

library(ncdf4)
ncdata <- nc_open(file)
lon <- ncvar_get(ncdata, "Longitude")
lat <- ncvar_get(ncdata, "Latitude")
temp <-ncvar_get(ncdata,"temperature")
str(temp)

num [1:4500,1:512,1:33] 24.7 24.6 24.6 24.7 24.7 ......

如何从阵列上方找到特定温度(25)的深度?然后将其子集到小区域?

1 个答案:

答案 0 :(得分:0)

扩展@Richard Telford回复,你只需在所有像素的z维度上应用一个函数,该函数计算温度与25度相交的深度。阈值。

很简单,你可以这样做:

file <- "http://ncss.hycom.org/thredds/ncss/GLBa0.08/latest/temp?var=temperature&north=25&west=74.1199&east=434.1199&south=-15&horizStride=1&time_start=2016-09-27T00%3A00%3A00Z&time_end=2016-09-27T23%3A59%3A00Z&timeStride=1&vertCoord=&accept=netcdf4"
savefile = tempfile(, fileext = "nc4")
download.file(file, savefile)
library(ncdf4)
ncdata <- nc_open(savefile)
lon <- ncvar_get(ncdata, "Longitude")  
lat <- ncvar_get(ncdata, "Latitude") 
temp <-ncvar_get(ncdata,"temperature")

temp <- temp [,,1:10] # subset depths to speed up
depths <- 1:10  # let's define some dummy depths - you want to put actual values, here !

finddepth = function(pixtemp, ...) {
  if (max(pixtemp, na.rm = TRUE) < predtemp$temp) {
    NA    # set to NA if no values >= 25
  } else {
    depth <- tryCatch({
      depth <- approx(pixtemp, depths,predtemp$temp)$y # interpolate using linear (faster)
      # interp  <- loess(depths~pixtemp)  # interpolate using loess  (slower - deals with non-linearity)
      # depth  <- predict(interp, predtemp$temp) # find depth @ temperature
      return(depth)   # send back computed depth
    }, error = function(e) {NA}
    )

  }
}
predtemp  <- data.frame(temp = 25)   # set desired isotherm
iso_depth <- apply(temp, c(1, 2), FUN = finddepth)

(我认为)在“iso_depth”中提供所需的数据:

library(lattice)
levelplot(iso_depth, main = "Isotherm depth", col.regions = terrain.colors(250))

enter image description here

(在图像中,白色区域对应于不存在25°等温线的点@,因为最高温度<25°)。

这里我通过“约”使用线性插值来找到深度@,其中T> T的最后深度之间的直线。 25和第一个@T&lt; 25与T = 25水平相交。如果线性插值不适合你,你可以在“深度&lt; - approx(...)”之后取消注释这两行,你将使用黄土局部二次插值(然而它更慢并且给出更多NA)。

请注意,为了获得“有意义”的值,您必须使用正确的深度值替换我设置的虚拟“深度”变量。

。另请注意,这非常缓慢:更复杂的方法可以提高速度。通过实现并行处理,您可以获得很快的速度。

@sudheera以前的迭代都崩溃了,因为有些像素只有3个非NA值,而try catch构造有一个错误。

HTH

洛伦佐