简体   繁体   中英

how to extract value from four dimensional netCDF data in R?

I have been searching for this quite a while, but still could not figure this out. Seems like the raster package is the one to extract, but only from two-dimensional data.

This example of four-dimensional data, a netCDF file contains hourly pressure level (4 levels) air temperatures for three consecutive days (72 hours). https://drive.google.com/file/d/1UIiX9-xHrtH2FT1torg53iPxyzLxSYQu/view?usp=sharing .

i just want to extact temperature at some point locations (xy), on its correspoding datetime and altitude (pressure level). Then add this as an additional column in this reference data:

ref_df <- structure(list(Latitude = c(40.68, 45.64, 50.31, 51.17, 
44.493564), Longitude = c(96.29, 97.107, 98.21, 
100.67, 105.01), timestamp = c("2019-05-01 15:52:14", 
"2019-05-01 18:52:29", "2019-05-02 21:52:30", "2019-05-03 00:52:29", 
"2019-05-03 03:52:15"), altitude_hPa = c(530, 570, 590, 600, 
610)), class = "data.frame", row.names = c(NA, -5L)) 

I tried below, following along this Import 4 dimensional netCDF data into R : but does not seem to work.

library(ncdf4)
ncdata <- nc_open(ncfile)
temp <- ncvar_get(ncdata)
dim(temp) # this shows index of layers in each dimention, but how to link this?

I appreciate it if anyone could help. Bat

The raster package is set up for 3-dimensional data (x, y and time) but you can loop over the 4th dimension. Here with lapply :

library(raster)
xy <- matrix(c(96.29, 97.11, 98.21, 100.67, 105.01, 40.68, 45.64, 50.31, 51.17, 44.49), ncol=2)
colnames(xy) <- c("lon", "lat")

v <- lapply(1:4, function(i) {
      b <- brick("download.nc", level=i)
      s <-  extract(b, xy)
    })

v is a list with four elements (one for each pressure level). Each element has a matrix with the same number of rows as xy and the same number of columns as the number of dates in download.nc

Or get a single matrix like this:

v <- lapply(1:4, function(i) {
      b <- brick("download.nc", level=i)
      s <- cbind(level=i, extract(b, xy))
    })  

vv <- do.call(rbind, v)

vv[1:8, 1:3]
#      level X2019.05.01.00.00.00 X2019.05.01.01.00.00
#[1,]     1             259.8976             259.9743
#[2,]     1             254.7902             255.7008
#[3,]     1             250.4961             250.6820
#[4,]     1             251.0643             250.8548
#[5,]     1             250.0989             250.1968
#[6,]     2             265.6487             265.6842
#[7,]     2             258.4251             259.0856
#[8,]     2             256.4043             256.4468

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM