[R-sig-Geo] add spatraster layers by matching a dataframe column and make spatio-temporal rast

Marta Rufino m@rt@@m@ru||no @end|ng |rom gm@||@com
Mon May 13 12:56:16 CEST 2024


Hi,

I would like to add layers to a spatraster (terra), by matching (joining) a
column in a data frame with the values of the raster layer (A).
Then, I would like to make it a spatio-temporal terra spatraster and/or a
stars (B).

Any help will be strongly appreciated,
Kind regards,
M.
________________________________________
 require(terra)

# A)

# runnable example
# Make an example raster:
  r = terra::rast(ncols=10, nrows=10)
  values(r) <- 1:100
  names(r)="ID"
  # add some missing values (to make it real)
  r[c(2,43,60,94)]=NA
  plot(r)

  # Make an example data frame (note both have an ID col to match)
  d <- data.frame(
    ID=100:1,
    k=c("aa","bb"),
    e=rnorm(100,2),
    year=sample(2001:2002, 100, replace = TRUE),
    date= as.Date(rep(c("2010-01-01", "2012-02-01",
"2010-03-01","2010-04-01"), l=100)))
  head(d)

# My tries:

  # 1. This works, but only for one col and it is not so nice:
  r$year2 <- d$year[match(as.vector(r$ID), d$ID)]
  plot(r)

  # 2. try it using app function: I could not make it work
  kk1 <- function(i,j=d) {
      j[match(as.vector(i$ID), j$ID),]
    }
  app(r, fun = kk1)

  # 3. try it using classify function
  # works with numeric (not characters) but it is not perfect
  terra::classify(r, d) # error
  # two numeric cols: works, but add the second col as the first raster
col. Not ok.
  terra::classify(r, d[,c(1,3)])
  # excluding the character col: gives an error
  terra::classify(r, d[,-c(2)])

  # 4. try it using merge function
  terra::merge(r, d) %>% head() #not sure what he did and in which order :(
but clearly not match/join working properly

  # 5. only (not elegant) way I managed:
  rast(
    left_join(
      as_tibble(r, xy=TRUE), d, by="ID"), type="xyz", crs = "EPSG:4326")
%>% plot()

# B) Make terra r raster a spatiotemporal cube

# 1.
#
https://stackoverflow.com/questions/74079441/group-raster-files-by-week-month
terra::time(r, tstep="years") <- d$year
# gives an error...
# Error: [time<-] length(value) != nlyr(x)

# 2.
#
https://stackoverflow.com/questions/74934891/specifying-layers-when-using-rast-type-xyz-to-convert-data-frame-to-spatra
# but I think this is not really a spatio-temporal rast...
d2 <- left_join(as_tibble(r, xy=TRUE), d, by=c("ID"))
w <- reshape(d2, timevar="year", idvar=c("x", "y"), direction="wide")
x <- rast(w, type="xyz")

# by year
d3 <- split(d2[,-7], d2$year)
r2 <- lapply(d3, \(i) rast(i, type="xyz"))
(r2 <- rast(r2))
time(r2) <- as.Date(names(r2))
plot(r2)

# plot with rasterVis
require(rasterVis)
levelplot(r2)


# 2. using stars (aternative)
# sources:
https://stackoverflow.com/questions/77368957/how-to-transform-a-sf-table-to-a-stars-cube-with-starsst-as-stars-function
# (
https://gis.stackexchange.com/questions/353741/generate-a-stars-object-from-tabular-spatial-temporal-data
):

s <- st_as_stars(as.data.frame(r, xy = TRUE, na.rm = TRUE), dims = c("x",
"y", "year"), crs = 4326)
s %>% plot(axes=TRUE)
# but the from and to of the year are wrong
# How to change to spatrast again?

	[[alternative HTML version deleted]]



More information about the R-sig-Geo mailing list