为什么R netCDF4软件包正在转置我的数据?

问题描述 投票:0回答:1

我正在使用ncdf4和RNetCDF读取R中的.nc数据。 NetCDF元数据说有144 lons和73 lats,导致144列73行。

但是,我在R中获得的数据似乎换成了144行和73列。

请您告诉我怎么了?

谢谢

    library(ncdf4)
    a <- tempfile()
    download.file(url = "ftp://ftp.cdc.noaa.gov/Datasets/ncep.reanalysis2.derived/pressure/uwnd.mon.mean.nc", destfile = a)
    nc <- nc_open(a)
    print(nc)
    File uwnd.mon.mean.nc (NC_FORMAT_CLASSIC):

         2 variables (excluding dimension variables):
            double time_bnds[nbnds,time]   
                long_name: Time Boundaries
            short uwnd[lon,lat,level,time]   
                long_name: Monthly U-wind on Pressure Levels
                valid_range: -32765
                 valid_range: -1266
                unpacked_valid_range: -140
                 unpacked_valid_range: 175
                actual_range: -58.9100112915039
                 actual_range: 103.155143737793
                units: m/s
                add_offset: 187.649993896484
                scale_factor: 0.00999999977648258
                missing_value: 32766
                _FillValue: -32767
                precision: 2
                least_significant_digit: 1
                GRIB_id: 33
                GRIB_name: UGRD
                var_desc: u-wind
                dataset: NCEP/DOE AMIP-II Reanalysis (Reanalysis-2) Monthly Averages
                level_desc: Pressure Levels
                statistic: Individual Obs
                parent_stat: Other
                standard_name: eastward_wind
                cell_methods: time: mean (monthly from 6-hourly values)

         5 dimensions:
            lon  Size:144
                units: degrees_east
                long_name: Longitude
                actual_range: 0
                 actual_range: 357.5
                standard_name: longitude
                axis: X
                coordinate_defines: point
            lat  Size:73
                units: degrees_north
                actual_range: 90
                 actual_range: -90
                long_name: Latitude
                standard_name: latitude
                axis: Y
                coordinate_defines: point
            level  Size:17
                units: millibar
                actual_range: 1000
                 actual_range: 10
                long_name: Level
                positive: down
                GRIB_id: 100
                GRIB_name: hPa
                axis: Z
                coordinate_defines: point

    uwnd <- ncvar_get(nc = ncu, varid = "uwnd")
    dim(uwnd)
    [1] 144  73  17 494
    umed <- (uwnd[ , , 10, 421] + uwnd[ , , 10, 422] + uwnd[ , , 10, 423])/3
    nrow(umed)
    [1] 144
    ncol(umed)
    [1] 73
r netcdf
1个回答
0
投票

看来您有两个问题。

[[[[[第一个]]与期望netCDF文件在R中具有相同的结构有关,这本身就是一个问题,因为当您将netCDF的多维数组结构转换为二维时数据框。 NetCDF格式需要在R中进行一些重塑,以便像在python中一样进行操作(请参阅:http://geog.uoregon.edu/bartlein/courses/geog490/week04-netCDF.html)。

[[第二个

] >>是在设置数据子集时使用的是值而不是索引。
umed <- (uwnd[ , , 10, 421] + uwnd[ , , 10, 422] + uwnd[ , , 10, 423])/3
我看到的

解决方案

首先是创建要子集的维度的索引。在此示例中,我将置信水平设置为10毫巴,所有范围都在经度230和300之间以及纬度25和40之间。
nc <- nc_open("uwnd.mon.mean.nc")

LonIdx <- which( nc$dim$lon$vals > 230 & nc$dim$lon$vals <300 )
## [1]  94  95  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 112 113         
## 114 115 116 117 118 119 120
LatIdx <- which( nc$dim$lat$vals >25  & nc$dim$lat$vals < 40)
## [1] 22 23 24 25 26
LevIdx <- which( nc$dim$level$vals==10)
## [1] 17

然后,您需要在每个维度上应用索引,但我认为您不希望将其作为子集使用时间。子设置lon和latitude很重要,因为R将所有内容保存在内存中,因此,将它们全部保留下来会消耗大量RAM。

lat <- ncvar_get(nc,"lat")[LatIdx]
lon <- ncvar_get(nc,"lon")[LonIdx] 
lev <- ncvar_get(nc,"level")[LevIdx]
time <- ncvar_get(nc,"time")

此后,您可以获取要查找的变量压力水平上的每月每月U型风

,并使用nc_close(nc)完成读取netCDF文件。
uwnd <- ncvar_get(nc,"uwnd")[LonIdx,LatIdx,LevIdx,] 
nc_close(nc)

最后,您可以使用所有四个维度来扩展网格:经度,纬度,压力级别和时间。

uwndf <- data.frame(as.matrix(cbind(expand.grid(lon,lat,lev,time))),c(uwnd))
names(uwndf) <- c("lon","lat","level","time","U-wind")

将其绑定到具有U-wind变量的数据帧,并将netcdf时间变量转换为R时间对象。

uwndf$time_final<-convertDateNcdf2R(uwndf$time, units = "hours", origin =          
as.POSIXct("1800-01-01",  tz = "UTC"),time.format="%Y-%m-%d %Z %H:%M:%S")

最后,您将获得所需的数据帧,范围是1979年1月至2020年3月。

max(uwndf$time_final)
## [1] "2020-03-01 UTC"
min(uwndf$time_final)
## [1] "1979-01-01 UTC"
head(uwndf)
##     lon  lat level    time    U-wind time_final
## 1 232.5 37.5    10 1569072  3.289998 1979-01-01
## 2 235.0 37.5    10 1569072  5.209998 1979-01-01
## 3 237.5 37.5    10 1569072  7.409998 1979-01-01
## 4 240.0 37.5    10 1569072  9.749998 1979-01-01
## 5 242.5 37.5    10 1569072 12.009998 1979-01-01
## 6 245.0 37.5    10 1569072 14.089998 1979-01-01

我希望这是有用的!干杯!

注意:要将netcdf时间变量转换为R时间对象,请确保已安装ncdf.tools库。

© www.soinside.com 2019 - 2024. All rights reserved.