R循环:按变量命名目标

时间:2022-01-12 00:10:14

I need to read daily netcdf files every month and give each a name ended with the date

我需要每个月阅读每日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
}

In the end I should have raster objectives named as sm01 sm02 . . . sm31

最后我应该有名为sm01 sm02的栅格目标。 。 。 SM31

for January. There must be a simple way to do it, I'm just very fresh in coding.

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

2 个解决方案

#1


1  

You want to take a mean of a set of raster files. Package raster has built-in object types for handling situations such as this. It is much more efficient to create a rasterStack and use calc to find the mean:

你想要取一组光栅文件的意思。包栅格具有内置对象类型,用于处理此类情况。创建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 )

Edit based on OP comment

You cannot pass a list of filenames directly to raster. From the manual, it states:

您无法将文件名列表直接传递给栅格。从手册中可以看出:

x: filename (character), Extent, Raster*, SpatialPixels*, SpatialGrid*, object, 'image', matrix, im, or missing.

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

Therefore if you must have individual raster objects (and I strongly advise against it in this case) then you could use your loop as originally planned, or you could use:

因此,如果你必须有单独的光栅对象(在这种情况下我强烈反对它),那么你可以按原计划使用你的循环,或者你可以使用:

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

This will return one list object, each element of which is a raster object. This is probably not that useful to you, but you can then access each one using smRaster[[1]] , smRaster[[2]] etc.

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

But use a raster stack if your files have the same extent and resolution!

Reading the files in using stack is likely to be more efficient and help you write more readable, shorter code. You can operate on all the rasters at once using convenient syntax, e.g. if I wanted to make a new raster that showed the sum of all the other rasters:

使用堆栈读取文件可能更有效,并帮助您编写更易读,更短的代码。您可以使用方便的语法一次操作所有栅格,例如如果我想制作一个显示所有其他栅格总和的新栅格:

## 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)

I would really strongly advise using a stack if you rasters cover the same spatial extent and resolution. It is more efficient, both for R and for your coding to just use a stack! I hope I have convinced you! :-)

如果你的光栅覆盖相同的空间范围和分辨率,我真的强烈建议使用堆栈。对于R和编码来说它只是使用堆栈更高效!我希望我已经说服你了! :-)

#2


0  

First thing: your for loop is off, you only iterate over one value, 31. You need to change it to:

第一件事:你的for循环关闭,你只迭代一个值,31。你需要将它改为:

for (monthd in 1 : 31) { …

Next, to create a variable based on a string, use assign:

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

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

Finally, remove the last line of your loop – it’s syntactically wrong and it achieves nothing, once corrected.

最后,删除循环的最后一行 - 它在语法上是错误的,一旦纠正就没有任何结果。

However, I strongly advise against using assign here. What you want isn’t lots of individual variables, you simply want a vector. You can simply create it like this:

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

sm <- vector(length = 31)
# or
sm <- 1 : 31
# or, same as previous
sm <- seq(1, 31)
# or
sm <- rep(someValue, 31)

#1


1  

You want to take a mean of a set of raster files. Package raster has built-in object types for handling situations such as this. It is much more efficient to create a rasterStack and use calc to find the mean:

你想要取一组光栅文件的意思。包栅格具有内置对象类型,用于处理此类情况。创建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 )

Edit based on OP comment

You cannot pass a list of filenames directly to raster. From the manual, it states:

您无法将文件名列表直接传递给栅格。从手册中可以看出:

x: filename (character), Extent, Raster*, SpatialPixels*, SpatialGrid*, object, 'image', matrix, im, or missing.

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

Therefore if you must have individual raster objects (and I strongly advise against it in this case) then you could use your loop as originally planned, or you could use:

因此,如果你必须有单独的光栅对象(在这种情况下我强烈反对它),那么你可以按原计划使用你的循环,或者你可以使用:

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

This will return one list object, each element of which is a raster object. This is probably not that useful to you, but you can then access each one using smRaster[[1]] , smRaster[[2]] etc.

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

But use a raster stack if your files have the same extent and resolution!

Reading the files in using stack is likely to be more efficient and help you write more readable, shorter code. You can operate on all the rasters at once using convenient syntax, e.g. if I wanted to make a new raster that showed the sum of all the other rasters:

使用堆栈读取文件可能更有效,并帮助您编写更易读,更短的代码。您可以使用方便的语法一次操作所有栅格,例如如果我想制作一个显示所有其他栅格总和的新栅格:

## 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)

I would really strongly advise using a stack if you rasters cover the same spatial extent and resolution. It is more efficient, both for R and for your coding to just use a stack! I hope I have convinced you! :-)

如果你的光栅覆盖相同的空间范围和分辨率,我真的强烈建议使用堆栈。对于R和编码来说它只是使用堆栈更高效!我希望我已经说服你了! :-)

#2


0  

First thing: your for loop is off, you only iterate over one value, 31. You need to change it to:

第一件事:你的for循环关闭,你只迭代一个值,31。你需要将它改为:

for (monthd in 1 : 31) { …

Next, to create a variable based on a string, use assign:

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

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

Finally, remove the last line of your loop – it’s syntactically wrong and it achieves nothing, once corrected.

最后,删除循环的最后一行 - 它在语法上是错误的,一旦纠正就没有任何结果。

However, I strongly advise against using assign here. What you want isn’t lots of individual variables, you simply want a vector. You can simply create it like this:

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

sm <- vector(length = 31)
# or
sm <- 1 : 31
# or, same as previous
sm <- seq(1, 31)
# or
sm <- rep(someValue, 31)