简体   繁体   English

使用 TERRA package 从插值栅格计算长期平均月降雨量?

[英]Calculating long-term mean monthly rainfall from interpolated rasters using TERRA package?

I have a SpatRaster object in R called IDW3, estimated using IDW interpolation method.我在 R 中有一个名为 IDW3 的 SpatRaster object,估计使用 IDW 插值方法。 I have nlyr = 240 , containing 12 months x 20 years.我有nlyr = 240 ,包含 12 个月 x 20 年。 I need to calculate the long-term mean monthly rainfall from the layers, so that I get nlyr = 12 at the end, in which each layer represents one calendar month (Jan - Dec).我需要计算各层的长期平均月降雨量,以便最后得到nlyr = 12 ,其中每一层代表一个日历月(1 月 - 12 月)。

I have tried using the code below, following this thread calculating long term daily means from a RASTER in R , but I want to verify the code I used.我尝试使用下面的代码,按照这个线程从 R 中的 RASTER 计算长期每日平均值,但我想验证我使用的代码。

Any thoughts and comments please?请问有什么想法和意见吗?

idw3
#> class       : SpatRaster 
#> dimensions  : 723, 449, 240  (nrow, ncol, nlyr)
#> resolution  : 100, 100  (x, y)
#> extent      : 624698.7, 669598.7, 640507.8, 712807.8  (xmin, xmax, ymin, ymax)
#> coord. ref. :  
#> sources     : May 1998_masked_idw3.asc  
#>               May 1999_masked_idw3.asc  
#>               May 2000_masked_idw3.asc  
#>               ... and 237 more source(s)
#> names       :     Jan 1998,     Jan 1999,     Jan 2000,     Jan 2001,     #> Jan 2002,     Jan 2003, ... 
#> min values  :           ? ,           ? ,           ? ,           ? ,           ? ,           ? , ... 
#> max values  :           ? ,           ? ,           ? ,           ? ,           ? ,           ? , ... 

## CALCULATE THE LONGTERM MONTHLY MEANS
# get the months substring
month.ltm <- substr(my, 1,3)

# calculate the ltm using tapp funtion in terra
idw3.ltm <- tapp(idw3, month.ltm, mean)
names(idw3.ltm)
#> [1] "May" "Apr" "Aug" "Jan" "Sep" "Jul" "Jun" "Feb" "Dec"
#> [10] "Nov" "Oct" "Mar"

It's been some time since you posted this, but I'd try to solve this for the next one asking.自从您发布此内容以来已经有一段时间了,但是我会尝试为下一个问题解决这个问题。 Since your example does not seem to be fully reproducible, let my use my own data for this purpose.由于您的示例似乎无法完全重现,因此请让我使用自己的数据来实现此目的。

I used GPCC v2022 data - the last two decades of monthly data at 0.5° resolution to be precise - from German Weather Service.我使用了来自德国气象局的GPCC v2022 数据——准确地说是 0.5° 分辨率的过去 20 年的月度数据。

library(terra)
#> terra 1.5.21

# define filenames
files <- c("full_data_monthly_v2022_2001_2010_05.nc",
           "full_data_monthly_v2022_2011_2020_05.nc")

# create SpatRaster object
nc_data <- rast(files)

# get variable names
varnames(nc_data)
#>  [1] "precip"                       "numgauge"                    
#>  [3] "infilled_numgauges"           "interpolation_error"         
#>  [5] "interpolation_error_infilled" "diff_new_old_method"         
#>  [7] "precip"                       "numgauge"                    
#>  [9] "infilled_numgauges"           "interpolation_error"         
#> [11] "interpolation_error_infilled" "diff_new_old_method"

# subset dataset to precipitation only
nc_precip <- nc_data["precip"]

# sneak peek
nc_precip
#> class       : SpatRaster 
#> dimensions  : 360, 720, 240  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : full_data_monthly_v2022_2001_2010_05.nc:precip  (120 layers) 
#>               full_data_monthly_v2022_2011_2020_05.nc:precip  (120 layers) 
#> varnames    : precip (gpcc full data monthly product version 2022, precipitation per grid) 
#>               precip (gpcc full data monthly product version 2022, precipitation per grid) 
#> names       : precip_1, precip_2, precip_3, precip_4, precip_5, precip_6, ... 
#> unit        : mm/month, mm/month, mm/month, mm/month, mm/month, mm/month, ... 
#> time        : 2001-01-01 to 2020-12-01

As you can see, this dataset is quite similar to yours in terms of information at least (except for crs, extent and resolution).正如你所看到的,这个数据集至少在信息方面与你的非常相似(除了 crs、extent 和 resolution)。 A stack of SpatRaster objects with nlyr = 240 containing monthly precipitation data.包含月降水数据的nlyr = 240的 SpatRaster 对象堆栈。 What differs most notably is the time attribute ranging from 2001-01-01 to 2020-12-01.最显着的不同是从 2001-01-01 到 2020-12-01 的time属性。

However, basically I approached your issue constructing an appropriate time-based index vector as input to tapp using fun = mean :但是,基本上,我使用fun = mean解决了构建适当的基于时间的索引向量作为tapp的输入的问题:

# get timestamps from your SpatRaster object
tst <- terra::time(nc_precip) 

# calculate monthly means
lta <- tapp(nc_precip, index = 1:12, fun = mean)

# tidy your names a little bit
names(lta) <- format(tst, "%B") |> unique()

# inspect result
lta
#> class       : SpatRaster 
#> dimensions  : 360, 720, 12  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : memory  
#>               memory  
#>               memory  
#>               ... and 9 more source(s)
#> names       :   January,  February,     March,     April,       May,      June, ... 
#> min values  :         0,         0,         0,         0,         0,         0,     ... 
#> max values  :  979.1880,  852.0020,  720.6245,  739.8225,  884.2455, 1590.6805,     ...

The result seems plausible from my point of view, but since this is the first time I used tapp , I want to make sure the function behaves as expected by re-calculating manually:从我的角度来看,结果似乎是合理的,但由于这是我第一次使用tapp ,我想通过手动重新计算来确保 function 的行为符合预期:

# init an empty list for temporary storage purposes
lta <- list()

# loop monthly and calculate the long-term mean
for (i in 1:12) {
  
  idx <- seq(from = i, by = 12, length.out = n_years)
  
  lta[[i]] <- nc_precip[[idx]] |> terra::mean()
}

# create a SpatRast object with nlyr = 12
lta <- terra::rast(lta)

lta
#> class       : SpatRaster 
#> dimensions  : 360, 720, 12  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : memory  
#>               memory  
#>               memory  
#>               ... and 9 more source(s)
#> names       :      mean,      mean,      mean,      mean,      mean,      mean, ... 
#> min values  :         0,         0,         0,         0,         0,         0, ... 
#> max values  :  979.1880,  852.0020,  720.6245,  739.8225,  884.2455, 1590.6805, ...

Same results, phew.结果一样,呵呵。

Edit:编辑:

After some weird behaviour yesterday which cannot be reproduced today I can confirm that using index = months.abb gives you the same results as using index = "months" (as suggested by Roger below in the comments):在昨天发生了一些今天无法重现的奇怪行为之后,我可以确认使用index = months.abb给你的结果与使用index = "months"相同(正如 Roger 在下面的评论中所建议的那样):

tapp(nc_precip, index = month.abb, fun = mean)
#> class       : SpatRaster 
#> dimensions  : 360, 720, 12  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : memory 
#> names       :       Jan,       Feb,       Mar,       Apr,       May,       Jun, ... 
#> min values  :         0,         0,         0,         0,         0,         0, ... 
#> max values  :  979.1880,  852.0020,  720.6245,  739.8225,  884.2455, 1590.6805, ...

tapp(nc_precip, index = "months", fun = mean)
#> class       : SpatRaster 
#> dimensions  : 360, 720, 12  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : memory 
#> names       :        X1,        X2,        X3,        X4,        X5,        X6, ... 
#> min values  :         0,         0,         0,         0,         0,         0, ... 
#> max values  :  979.1880,  852.0020,  720.6245,  739.8225,  884.2455, 1590.6805, ...

You can use tapp for that.您可以为此使用tapp Here are some example data以下是一些示例数据

library(terra)
r <- rast(ncols=10, nrows=10, nlyr=24)
values(r) <- 1:size(r)

If the data are ordered by year, and then by month, you can now do如果数据按年排序,然后按月排序,您现在可以

x <- tapp(r, 1:12, mean)

In other cases you may have to create another index to match the layers that need to be combined.在其他情况下,您可能必须创建另一个索引来匹配需要组合的图层。 If your data has a time-stamp, there are some shortcuts.如果您的数据有时间戳,则有一些快捷方式。 In this case you can use index="months"在这种情况下,您可以使用index="months"

time(r) <- as.Date("2000-01-15") + 0:23 * 30.5
y <- tapp(r, "months", mean)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM