Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

terra::predict() drops or changes layer names based on the value of index #1194

Closed
mikemahoney218 opened this issue Jun 21, 2023 · 2 comments

Comments

@mikemahoney218
Copy link

mikemahoney218 commented Jun 21, 2023

Problem

The names returned by terra::predict() are partially dependent upon the value provided to index. My testing suggests that if index isn't provided, then any names returned by fun are used; if index is provided and the return has the same number of bands as the input raster, names of the input raster are used (even if that band wasn't used for calculations); and if index is longer than the number of input bands, the default lyr.1-type names are used.

I think ideally any names returned by fun would be preserved, irrespective of index.

reprex

library(terra)
#> terra 1.7.37

test <- rast(ncols = 1000, nrows = 1000, xmin=0)
values(test) <- rnorm(ncell(test))
names(test) <- "name_from_raster"

dummy_model <- list()

terra::predict(
  test, 
  dummy_model, 
  fun = function(object, newdata) { 
    return(data.frame(x = newdata[[1]] * 0.5))
  }
)
#> class       : SpatRaster 
#> dimensions  : 1000, 1000, 1  (nrow, ncol, nlyr)
#> resolution  : 0.18, 0.18  (x, y)
#> extent      : 0, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source(s)   : memory
#> name        :        x 
#> min value   : -2.53496 
#> max value   :  2.38629

terra::predict(
  test, 
  dummy_model, 
  fun = function(object, newdata) { 
    return(data.frame(x = newdata[[1]] * 0.5))
  },
  index = 1
)
#> class       : SpatRaster 
#> dimensions  : 1000, 1000, 1  (nrow, ncol, nlyr)
#> resolution  : 0.18, 0.18  (x, y)
#> extent      : 0, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source(s)   : memory
#> name        : name_from_raster 
#> min value   :         -2.53496 
#> max value   :          2.38629

terra::predict(
  test, 
  dummy_model, 
  fun = function(object, newdata) { 
    return(data.frame(x = newdata[[1]] * 0.5, y = newdata[[1]] * 2))
  },
  index = 1:2
)
#> class       : SpatRaster 
#> dimensions  : 1000, 1000, 2  (nrow, ncol, nlyr)
#> resolution  : 0.18, 0.18  (x, y)
#> extent      : 0, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source(s)   : memory
#> names       :     lyr1,       lyr2 
#> min values  : -2.53496, -10.139838 
#> max values  :  2.38629,   9.545159

terra::predict(
  c(test, setNames(test, "another_name")), 
  dummy_model, 
  fun = function(object, newdata) { 
    return(data.frame(x = newdata[[1]] * 0.5, y = newdata[[1]] * 2))
  },
  index = 1:2
)
#> class       : SpatRaster 
#> dimensions  : 1000, 1000, 2  (nrow, ncol, nlyr)
#> resolution  : 0.18, 0.18  (x, y)
#> extent      : 0, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source(s)   : memory
#> names       : name_from_raster, another_name 
#> min values  :         -2.53496,   -10.139838 
#> max values  :          2.38629,     9.545159

# `index` is documented as only accepting integers,
# so it's perhaps surprising this works at all
terra::predict(
  test, 
  dummy_model, 
  fun = function(object, newdata) { 
    return(data.frame(x = newdata[[1]] * 0.5, y = newdata[[1]] * 2))
  },
  index = c("x", "y")
)
#> class       : SpatRaster 
#> dimensions  : 1000, 1000, 2  (nrow, ncol, nlyr)
#> resolution  : 0.18, 0.18  (x, y)
#> extent      : 0, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source(s)   : memory
#> names       :     lyr1,       lyr2 
#> min values  : -2.53496, -10.139838 
#> max values  :  2.38629,   9.545159

Created on 2023-06-21 with reprex v2.0.2

Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.3.0 (2023-04-21)
#>  os       Ubuntu 22.04.2 LTS
#>  system   x86_64, linux-gnu
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       America/New_York
#>  date     2023-06-21
#>  pandoc   3.1.1 @ /usr/lib/rstudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package     * version date (UTC) lib source
#>  cli           3.6.1   2023-03-23 [1] CRAN (R 4.3.0)
#>  codetools     0.2-19  2023-02-01 [1] CRAN (R 4.3.0)
#>  digest        0.6.31  2022-12-11 [1] CRAN (R 4.3.0)
#>  evaluate      0.20    2023-01-17 [1] CRAN (R 4.3.0)
#>  fastmap       1.1.1   2023-02-24 [1] CRAN (R 4.3.0)
#>  fs            1.6.1   2023-02-06 [1] CRAN (R 4.3.0)
#>  glue          1.6.2   2022-02-24 [1] CRAN (R 4.3.0)
#>  htmltools     0.5.5   2023-03-23 [1] CRAN (R 4.3.0)
#>  knitr         1.42    2023-01-25 [1] CRAN (R 4.3.0)
#>  lifecycle     1.0.3   2022-10-07 [1] CRAN (R 4.3.0)
#>  magrittr      2.0.3   2022-03-30 [1] CRAN (R 4.3.0)
#>  purrr         1.0.1   2023-01-10 [1] CRAN (R 4.3.0)
#>  R.cache       0.16.0  2022-07-21 [1] CRAN (R 4.3.0)
#>  R.methodsS3   1.8.2   2022-06-13 [1] CRAN (R 4.3.0)
#>  R.oo          1.25.0  2022-06-12 [1] CRAN (R 4.3.0)
#>  R.utils       2.12.2  2022-11-11 [1] CRAN (R 4.3.0)
#>  Rcpp          1.0.10  2023-01-22 [1] CRAN (R 4.3.0)
#>  reprex        2.0.2   2022-08-17 [1] CRAN (R 4.3.0)
#>  rlang         1.1.1   2023-04-28 [1] CRAN (R 4.3.0)
#>  rmarkdown     2.21    2023-03-26 [1] CRAN (R 4.3.0)
#>  rstudioapi    0.14    2022-08-22 [1] CRAN (R 4.3.0)
#>  sessioninfo   1.2.2   2021-12-06 [1] CRAN (R 4.3.0)
#>  styler        1.9.1   2023-03-04 [1] CRAN (R 4.3.0)
#>  terra       * 1.7-37  2023-06-18 [1] CRAN (R 4.3.0)
#>  vctrs         0.6.2   2023-04-19 [1] CRAN (R 4.3.0)
#>  withr         2.5.0   2022-03-03 [1] CRAN (R 4.3.0)
#>  xfun          0.39    2023-04-20 [1] CRAN (R 4.3.0)
#>  yaml          2.3.7   2023-01-23 [1] CRAN (R 4.3.0)
#> 
#>  [1] /home/mikemahoney218/R/x86_64-pc-linux-gnu-library/4.3
#>  [2] /usr/local/lib/R/site-library
#>  [3] /usr/lib/R/site-library
#>  [4] /usr/lib/R/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────
@rhijmans
Copy link
Member

I agree and thank you for the helpful repex. It seems to work better now:


library(terra)
test <- rast(ncols = 1000, nrows = 1000, xmin=0)
values(test) <- rnorm(ncell(test))
names(test) <- "name_from_raster"

dummy_model <- list()

terra::predict(test, dummy_model, 
   fun = \(object, newdata) data.frame(x = newdata[[1]] * 0.5)) |> names()
#[1] "x"
 
terra::predict(test, dummy_model, index=1,
   fun = \(object, newdata) data.frame(x = newdata[[1]] * 0.5)) |> names()
#[1] "x"
 
terra::predict(test, dummy_model, index = 1:2, 
   fun = \(object, newdata) data.frame(x = newdata[[1]] * 0.5, y = newdata[[1]] * 2)) |> names()
#[1] "x" "y"
 
terra::predict(c(test, setNames(test, "another_name")), dummy_model, index=1:2,
   fun = \(object, newdata) data.frame(x = newdata[[1]] * 0.5, y = newdata[[1]] * 2)) |> names()
#[1] "x" "y"
   
terra::predict(c(test, setNames(test, "another_name")), dummy_model, index=c("x", "y"),
   fun = \(object, newdata) data.frame(x = newdata[[1]] * 0.5, y = newdata[[1]] * 2)) |> names()
#[1] "x" "y"

@mikemahoney218
Copy link
Author

Fantastic, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants