1

我需要每个月阅读每日 netcdf 文件,并给每个文件取一个以日期结尾的名称

library(raster)
year<-2004
startmonth<-1
for(monthd in 31){
    days<-formatC(monthd, width=2, flag="0")
    month<-formatC(startmonth,width=2,flag="0")
    sm=raster(paste(year,month,days,"1.nc",sep=""),varname="sm")
    monthd<monthd+1
}

最后,我应该将光栅目标命名为 sm01 sm02 。. . SM31

一月。必须有一个简单的方法来做到这一点,我只是在编码方面很新鲜。

4

2 回答 2

1

您想取一组光栅文件的平均值。包raster具有用于处理此类情况的内置对象类型。创建一个 rasterStack 并使用它来查找平均值要高效得多:calc

days<-formatC(1:31, width=2, flag="0")
files <- list( paste("2004" , "01" , days , "1.nc" , sep="" ) )

## First 3 filenames:
files[[1]][1:3]
# [1] "200401011.nc" "200401021.nc" "200401031.nc"

sms <- stack( files )
smMean <- calc( sms , mean , na.rm = TRUE )

根据 OP 评论编辑

您不能将文件名列表直接传递给光栅。从手册中,它指出:

x:文件名(字符)、范围、Raster*、SpatialPixels*、SpatialGrid*、对象、“图像”、矩阵、im 或缺失。

因此,如果您必须拥有单独的光栅对象(在这种情况下我强烈建议不要这样做),那么您可以按照最初的计划使用循环,或者您可以使用:

smRaster <- lapply( files , raster , varname = "sm" )

这将返回一个列表对象,其中的每个元素都是一个栅格对象。这可能对您没有多大用处,但您可以使用 等访问每smRaster[[1]]一个smRaster[[2]]

但是,如果您的文件具有相同的范围和分辨率,请使用光栅堆栈!

在 usingstack中读取文件可能会更高效,并帮助您编写更易读、更短的代码。您可以使用方便的语法一次对所有栅格进行操作,例如,如果我想创建一个显示所有其他栅格总和的新栅格:

## First we use our files list to make the rasterStack
smStack <- stack( files , varname = "sm" )

## 'sum' returns a new rasterLayer, each cell is the sum of the corresponding cells in the stack
smSum <- sum( smStack , na.rm = TRUE )

## 'mean' does the same!!
smMean <- mean( smStack , na.rm = TRUE )

## What if we want the mean of only the first 7 days of rasters?
smMean <- mean( smStack[[1:7]] , na.rm = TRUE )

## To see how many rasters in the stack...
nlayers( smStack )

## To make a new object of just the first 7 rasters in the stack
subset( smStack , 1:7 )

## Is roughly equivalent to using the `[[` operator like this to get the first 7 layers in a new object
newRaster <- smStack[[1:7]]

## If you want to access an individual layer..
smStack[[ layernumber/or layername here ]]

## And to get the names:
names( smStack)

如果您的栅格覆盖相同的空间范围和分辨率,我强烈建议您使用堆栈。对于 R 和您的编码而言,仅使用stack! 我希望我已经说服了你!:-)

于 2013-05-02T21:36:34.213 回答
0

第一件事:你的for循环是关闭的,你只迭代一个值,31. 您需要将其更改为:

for (monthd in 1 : 31) { …

接下来,要基于字符串创建变量,请使用assign

assign(paste('sm', monthd, sep = ''), someValue)

最后,删除循环的最后一行——它在语法上是错误的,一旦更正,它什么也得不到。

但是,我强烈建议不要assign在这里使用。您想要的不是很多单独的变量,您只需要一个vector。您可以像这样简单地创建它:

sm <- vector(length = 31)
# or
sm <- 1 : 31
# or, same as previous
sm <- seq(1, 31)
# or
sm <- rep(someValue, 31)
于 2013-05-02T19:19:02.483 回答