【问题标题】:Opening and reading multiple netcdf files with RnetCDF使用 RnetCDF 打开和读取多个 netcdf 文件
【发布时间】:2023-04-02 03:00:02
【问题描述】:

使用 R,我试图打开我在单个文件夹中的所有 netcdf 文件(例如 20 个文件),读取单个变量,并创建一个结合所有文件值的单个 data.frame。我一直在使用 RnetCDF 来读取 netcdf 文件。对于单个文件,我使用以下命令读取变量:

library('RNetCDF')
nc = open.nc('file.nc')
lw = var.get.nc(nc,'LWdown',start=c(414,315,1),count=c(1,1,240))

其中 414 和 315 是我要提取的值的经度和纬度,240 是时间步数。

我找到了this 线程,它解释了如何打开多个文件。在它之后,我设法使用以下方法打开文件:

 filenames= list.files('/MY_FOLDER/',pattern='*.nc',full.names=TRUE)
 ldf = lapply(filenames,open.nc)

但现在我被困住了。我试过了

  var1= lapply(ldf, var.get.nc(ldf,'LWdown',start=c(414,315,1),count=c(1,1,240)))

但它不起作用。 增加的复杂性是每个 nc 文件都有不同的时间步数。所以我有两个问题:

1:如何打开所有文件,读取每个文件中的变量并将所有值合并到一个数据框中? 2:如何将count中的最后一个维度设置为对所有文件都不同?

【问题讨论】:

  • 使用循环可能会更好,更容易对 i/o 假设进行测试,特别是如果每​​个文件都有不同的参数。很简单,编写适用于一个文件的第 i 个版本,然后围绕它循环 :)

标签: r netcdf


【解决方案1】:

根据@mdsummer 的评论,我尝试了一个 do 循环,并设法完成了我需要的一切:

# Declare data frame
df=NULL

#Open all files
files= list.files('MY_FOLDER/',pattern='*.nc',full.names=TRUE)

# Loop over files
for(i in seq_along(files)) {
nc = open.nc(files[i])

# Read the whole nc file and read the length of the varying dimension (here, the 3rd dimension, specifically time)
lw = var.get.nc(nc,'LWdown')
x=dim(lw)

# Vary the time dimension for each file as required
lw = var.get.nc(nc,'LWdown',start=c(414,315,1),count=c(1,1,x[3]))

# Add the values from each file to a single data.frame
rbind(df,data.frame(lw))->df
}

可能有一种更优雅的方式,但它确实有效。

【讨论】:

  • 考虑关闭每个连接而不是覆盖它,在 var.get.nc 之后使用 close.nc(nc)。
  • 嗨...如果可以,在 c(414,315,1) 中,值 '1' 是什么?怎么来纬度和经度是414、315,它们的单位是什么?以及 count(1,1,x[3]) 或时间步在这里是什么意思。我被困在那个部分?请告诉我
  • 我在这里讨论过类似的问题。 stackoverflow.com/questions/68521763/…
【解决方案2】:

您传递的附加函数参数错误。您应该为此使用...。这是一个如何将na.rm 传递给mean 的简单示例。

x.var <- 1:10
x.var[5] <- NA
x.var <- list(x.var)
x.var[[2]] <- 1:10
lapply(x.var, FUN = mean)
lapply(x.var, FUN = mean, na.rm = TRUE)

编辑

对于您的具体示例,这将类似于

var1 <- lapply(ldf, FUN = var.get.nc, variable = 'LWdown', start = c(414, 315, 1), count = c(1, 1, 240))

虽然这是未经测试的。

【讨论】:

  • 您能否让您的示例更适用于我的请求?我不能说你的回答现在对我有帮助。
  • @SnowFrog 只有前两个参数被传递给lapply,任何超出FUN 的参数都被传递给var.get.nc,因为它被认为是... 的一部分。
  • 使用上面的示例,将var1 打印到屏幕上会得到list()
  • @SnowFrog 没有可重复的例子很难判断。
【解决方案3】:

我认为使用 CDO 更容易做到这一点,因为您可以使用日期或时间戳轻松选择 可变 时间步,然后选择所需的最近网格点。这将是一个示例 bash 脚本:

# I don't know how your time axis is
# you may need to use a date with a time stamp too if your data is not e.g. daily
# see the CDO manual for how to define dates. 
date=20090101 
lat=10
lon=50

files=`ls MY_FOLDER/*.nc`
for file in $files ; do
  # select the nearest grid point and the date slice desired:
  # %??? strips the .nc from the file name
  cdo seldate,$date -remapnn,lon=$lon/lat=$lat $file ${file%???}_${lat}_${lon}_${date}.nc
done
Rscript here to read in the files

可以使用 cdo 合并所有新文件,但如果时间戳相同,则需要小心。您可以尝试 cdo mergecdo cat - 这样您就可以将单个文件读入 R,而不必分别循环和打开每个文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多