首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么R netCDF4包要转置我的数据?

为什么R netCDF4包要转置我的数据?
EN

Stack Overflow用户
提问于 2020-04-01 03:14:31
回答 1查看 128关注 0票数 0

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

然而,我在R中得到的数据似乎是144行和73列的转置。

你能告诉我出什么事了吗?

谢谢

代码语言:javascript
复制
    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)
    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
EN

回答 1

Stack Overflow用户

发布于 2020-04-16 18:55:45

看起来你有两个问题。

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

第二个是在设置数据子集时使用值而不是索引。

代码语言:javascript
复制
umed <- (uwnd[ , , 10, 421] + uwnd[ , , 10, 422] + uwnd[ , , 10, 423])/3

我看到的解决方案从创建您想要子集的维度的索引开始。在本例中,我设置了preassure级别10毫巴以及经度230到300之间和纬度25到40之间的所有子集。

代码语言:javascript
复制
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。

代码语言:javascript
复制
lat <- ncvar_get(nc,"lat")[LatIdx]
lon <- ncvar_get(nc,"lon")[LonIdx] 
lev <- ncvar_get(nc,"level")[LevIdx]
time <- ncvar_get(nc,"time")

在此之后,您可以获得您正在寻找的变量,每月U-wind的压力水平,并完成读取的nc_close(nc)文件的netCDF。

代码语言:javascript
复制
uwnd <- ncvar_get(nc,"uwnd")[LonIdx,LatIdx,LevIdx,] 
nc_close(nc)

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

代码语言:javascript
复制
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时间对象。

代码语言:javascript
复制
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月之间要查找的数据帧。

代码语言:javascript
复制
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库。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60958171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档