index not working on for loop created to read rasters from a directory, summarize data into single raster, 并输出新的栅格

index not working on for loop created to read rasters from a directory, summarize data into single raster, and output new raster

我有几个充满栅格的目录,这些栅格是每日气候数据。我需要将每日栅格合并为每周栅格,一些按值的总和,一些按值的平均值。到目前为止,我已经在目录中创建了一个文件名向量(其中包含每日栅格文件)并编写了一个 for 循环来导入前 7 个栅格,将栅格放入 stack , 使用 calcstack 中栅格的平均值(或总和)转换为单个新栅格,并将栅格写入工作目录中的文件。然后,我通过尝试从向量中删除前 7 个名称并对向量中剩余的前 7 个文件名重复循环来处理新的文件名向量。我遇到的问题是第一个索引文件名没有从向量中删除。这是代码。

#file names for rasters are in a column of data frame
fname <- (repDf$fname)

#get rid of first 5 values to start on Sunday
fname <- fname[-c(1:5)]

#look at beginning of fname vector
head(fname)
[1] "1980_6.asc"  "1980_7.asc"  "1980_8.asc"  "1980_9.asc"  "1980_10.asc" "1980_11.asc"

for (i in seq_along(fname)){
  f1 <- fname[[i]]
  f2 <- fname[[i+1]]  
  f3 <- fname[[i+2]]
  f4 <- fname[[i+3]]
  f5 <- fname[[i+4]]
  f6 <- fname[[i+5]]
  f7 <- fname[[i+6]]
  r1 <- raster(f1)
  r2 <- raster(f2)
  r3 <- raster(f3)
  r4 <- raster(f4)
  r5 <- raster(f5)
  r6 <- raster(f6)
  r7 <- raster(f7)
  s <- stack(r1,r2,r3,r4,r5,r6,r7)
  r <- calc(s, fun=sum)
  r <- r * 0.0393701
  r <- round(r, 2)
  writeRaster(x=r, filename=paste0("week_", i, sep=""), format="ascii", overwrite=TRUE)
  remove <- c(f1,f2,f3,f4,f5,f6,f7)
  fname <- fname[! fname %in% remove]
}

#Example RasterLayer (after loop has run twice)
print(r1)
class       : RasterLayer 
dimensions  : 227, 199, 45173  (nrow, ncol, ncell)
resolution  : 994.9749, 994.9749  (x, y)
extent      : 367500, 565500, -1325500, -1099641  (xmin, xmax, ymin, ymax)
coord. ref. : NA 
data source : G:\dailyPrism843\prcp80_30.asc 
names       : X1980_30 

#Example indexed file names (after loop has run twice)
f1
[1] "1980_30.asc"

#Example output raster (after loop has run twice)
print(r)
class       : RasterLayer 
dimensions  : 227, 199, 45173  (nrow, ncol, ncell)
resolution  : 994.9749, 994.9749  (x, y)
extent      : 367500, 565500, -1325500, -1099641  (xmin, xmax, ymin, ymax)
coord. ref. : NA 
data source : in memory
names       : layer 
values      : 1.02, 3.54  (min, max)
The problem can be seen here;

head(fname)
[1] "1980_13.asc" "1980_21.asc" "1980_29.asc" "1980_30.asc" "1980_31.asc" "1980_32.asc"

出于某种原因,将用作一周第一天的文件名保留在 fname 向量中,并且进入每周计算的文件不代表他们需要的天数。任何帮助是极大的赞赏。我会尝试提供一些示例文件以供使用,但这些文件非常大。

在您的代码中添加一些调试代码,您可以识别发生了什么(我已禁用处理部分,因为我没有文件或计算逻辑):

fname <- c(paste0("1980_", 6:40, ".asc"))
fname[1]
seq_along(fname) # vector from 1 to length of vector!!!

for (i in seq_along(fname)){
  print(i)
  print(paste("Size of fname:", length(fname)))
  print(head(fname))
  print(fname[i])
  f1 <- fname[[i]]
  f2 <- fname[[i+1]]  
  f3 <- fname[[i+2]]
  f4 <- fname[[i+3]]
  f5 <- fname[[i+4]]
  f6 <- fname[[i+5]]
  f7 <- fname[[i+6]]
#   r1 <- raster(f1)
#   r2 <- raster(f2)
#   r3 <- raster(f3)
#   r4 <- raster(f4)
#   r5 <- raster(f5)
#   r6 <- raster(f6)
#   r7 <- raster(f7)
#  s <- stack(r1,r2,r3,r4,r5,r6,r7)
#  r <- calc(s, fun=sum)
#  r <- r * 0.0393701
#  r <- round(r, 2)
#  writeRaster(x=r, filename=paste0("week_", i, sep=""), format="ascii", overwrite=TRUE)
  remove <- c(f1,f2,f3,f4,f5,f6,f7)
  fname <- fname[! fname %in% remove]
}

这将导致:

[1] 1
[1] "Size of fname: 35"
[1] "1980_6.asc"  "1980_7.asc"  "1980_8.asc"  "1980_9.asc"  "1980_10.asc" "1980_11.asc"
[1] 2
[1] "Size of fname: 28"
[1] "1980_13.asc" "1980_14.asc" "1980_15.asc" "1980_16.asc" "1980_17.asc" "1980_18.asc"
[1] 3
[1] "Size of fname: 21"
[1] "1980_13.asc" "1980_21.asc" "1980_22.asc" "1980_23.asc" "1980_24.asc" "1980_25.asc"
[1] 4
[1] "Size of fname: 14"
[1] "1980_13.asc" "1980_21.asc" "1980_29.asc" "1980_30.asc" "1980_31.asc" "1980_32.asc"
[1] 5
[1] "Size of fname: 7"
[1] "1980_13.asc" "1980_21.asc" "1980_29.asc" "1980_37.asc" "1980_38.asc" "1980_39.asc"
Error in fname[[i + 3]] : subscript out of bounds

原因是您遍历了预定义数量的 fname 向量项(在我的示例中 "seq_along" = 35)。

因此您删除了已处理的项目,但 i 并未重置为 1,而是在每次循环时递增。

而且,还有很多改进代码的空间(例如,不需要删除元素,只需循环向量元素;如何处理最后一个循环中错误的向量大小;为什么要使用 double方括号访问 fnames...)

轻松修改解决问题(无需优化代码):

修改循环:

for (i in seq(1,length(fname), by=7)) {

删除两行:

remove <- c(f1,f2,f3,f4,f5,f6,f7)
fname <- fname[! fname %in% remove]

并改为添加调试输出:

print( paste("processing files", f1, "to", f7))

这是通过从文件名向量创建 RasterStack 来使代码更简洁的方法

fname <- repDf$fname[-c(1:5)]

for (i in seq(1,length(fname), by=7)){
    s <- stack(fname[i:(i+6)])
    r <- sum(s) * 0.0393701
    r <- round(r, 2)
    writeRaster(r, filename=paste0("week_", i), format="ascii", overwrite=TRUE)
}