Reputation: 105
I have several directories full of rasters that are daily climate data. I need to combine the daily rasters into weekly rasters, some by sum of values and some by mean of values. So far, I've created a vector of the file names within the directories (which contains the daily raster files) and written a for
loop to import the first 7 rasters, put the rasters into a stack
, used calc
to get the mean (or sum) of the rasters in the stack
into a single new raster, and write the raster to a file within the working directory. I then deal with the new vector of file names by attempting to remove the first 7 names from the vector and repeating the loop on the first 7 remaining file names within the vector. The problem I am having is that the first indexed file name is not being removed from the vector. Here's the code.
#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:\dailyPrism\10843\prcp\1980_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"
For some reason, the file name that would have been used as the first day of the week is retained in the fname vector and the files that go into the weekly calculations don't represent the days that they need to. Any help is greatly appreciated. I would try and provide some example files to work with, but the files are quite large.
Upvotes: 0
Views: 153
Reputation: 47146
Here is how you make the code more succinct by creating a RasterStack from a vector of filenames
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)
}
Upvotes: 1
Reputation: 8760
Add some debug code to your code and you can recognize what happens (I have disabled the processing part since I do not have files or calculation logic):
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]
}
This will result in:
[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
The reason is that you loop over a predefined number of fname vector items ("seq_along" = 35 in my example).
Therefore you delete the processed items but i is NOT reset to one but is incremented every time you loop through.
And puh, there is much room to improve the code (e. g. no need to delete the elements, just loop over the vector elements; how to deal with a wrong vector size in the last loop; why do you use double square brackets to access the fnames...)
Easy modifications to solve the problem (without optimizing the code):
Modify the loop:
for (i in seq(1,length(fname), by=7)) {
Remove the two lines:
remove <- c(f1,f2,f3,f4,f5,f6,f7)
fname <- fname[! fname %in% remove]
and add a debug output instead:
print( paste("processing files", f1, "to", f7))
Upvotes: 1