I have a simple csv file with lon/lat/time/values columns:
df <- data.frame(longitude=rep(c(10.5,11,12),10),
latitude=rep(c(10.5,11,12),10),
date= as.Date(rep(c("2012-01-01", "2012-02-01", "2012-03-01"), 10)),
vals=rnorm(30,10,5))
I'd like to convert this to a SpatRaster using the S4 method for signature 'data.frame'
rast(x, type="xyz", crs="", digits=6, extent=NULL)
, where each "date" would be a seperate layer.
Importing without the date works fine:
df.subset <- select(df,-date)
tmp <- terra::rast(df.subset, type="xyz")
I've tried to split the SpatRaster by date but get a Error in .local(x, f, ...) : length(f) == nlyr(x) is not TRUE
error:
split(tmp, as.factor(df$date))
I can think of an approach using a loop that
splits the df by date:
split(df, c("2012-01-01", "2012-02-01", "2012-03-01"))
creates seperate SpatRasters for each individual date
Use
merge
to combine individual SpatRasters with named layers
Is there a tidier way of doing this in terra?
CodePudding user response:
You can use one of the apply
functions to make a list of rasters and then use rast
again on this list.
library(terra)
library(dplyr)
# I changed the data so that different dates have many locations
# rast complains otherwise
df <- data.frame(longitude=rep(c(10.5,11,12),10),
latitude=rep(c(10.5,11,12),10),
date= as.Date(c(rep("2012-01-01", 10), rep("2012-02-01", 10), rep("2012-03-01", 10))),
vals=rnorm(30,10,5))
# A function to filter for dates
# and remove the date column (change this if you want to keep it)
myrast <- function(df, date_to_filter) {
df1 <- df %>% filter(date == date_to_filter) %>% select(-date)
raster_return <- rast(x = df1, type='xyz')
raster_return
}
# Iterate over all the unique dates
rr <- sapply(unique(df$date), function(d) myrast(df, d))
# Combine the list of raster objects
rr_all <- rast(rr)
plot(rr_all)
CodePudding user response:
Here is how you can use split
or reshape
Example data
library(terra)
set.seed(0)
df <- data.frame(longitude=rep(seq(10,19,1), 3),
latitude=rep(seq(10, 19,1), 3),
date= as.Date(rep(c("2012-01-01", "2012-02-01", "2012-03-01"), each=10)),
vals=rnorm(30,10,5))
reshape
w <- reshape(df, timevar="date", idvar=c("longitude", "latitude"), direction="wide")
x <- rast(w, type="xyz")
split
r <- split(df[,-3], df$date)
r <- lapply(r, \(i) rast(i, type="xyz"))
r <- rast(r)
# and perhaps
time(r) <- as.Date(names(r))
r
#class : SpatRaster
#dimensions : 10, 10, 3 (nrow, ncol, nlyr)
#resolution : 1, 1 (x, y)
#extent : 9.5, 19.5, 9.5, 19.5 (xmin, xmax, ymin, ymax)
#coord. ref. :
#source(s) : memory
#names : 2012-01-01, 2012-02-01, 2012-03-01
#min values : 2.30025, 3.812308, 3.577003
#max values : 22.02327, 13.817967, 15.428847
time (days) : 2012-01-01 to 2012-03-01
You could also do the splitting "manually", inside the lapply
loop
ud <- unique(df$date)
x <- lapply(ud, \(d) rast(df[df$date == d, -3], type="xyz"))
x <- rast(x)
names(x) <- ud