r-lib / rlang

Low-level API for programming with R
https://rlang.r-lib.org
Other
501 stars 137 forks source link

Feature request: vctrs-friendly scale mapping #1750

Closed teunbrand closed 3 hours ago

teunbrand commented 4 hours ago

Essentially, the code below should return a <foo> class rcrd vector, not a mangled list.

library(ggplot2)

rcrd <- vctrs::new_rcrd(list(foo = LETTERS[1:3], bar = 1:3), class = "foo")

p <- ggplot(mpg, aes(displ, hwy, colour = drv)) +
  geom_point() +
  scale_colour_manual(
    values = rcrd,
    na.value = NA
  )

options(max.print = 10)
head(layer_data(p)$colour)
#> Warning in ans[npos] <- rep(no, length.out = len)[npos]: number of items to
#> replace is not a multiple of replacement length
#> [[1]]
#>  [1] "B" "B" "B" "B" "B" "B" "B" "A" "A" "A"
#>  [ reached getOption("max.print") -- omitted 224 entries ]
#> 
#> [[2]]
#>  [1] 2 2 2 2 2 2 2 1 1 1
#>  [ reached getOption("max.print") -- omitted 224 entries ]
#> 
#> [[3]]
#>  [1] "B" "B" "B" "B" "B" "B" "B" "A" "A" "A"
#>  [ reached getOption("max.print") -- omitted 224 entries ]
#> 
#> [[4]]
#>  [1] 2 2 2 2 2 2 2 1 1 1
#>  [ reached getOption("max.print") -- omitted 224 entries ]
#> 
#> [[5]]
#>  [1] "B" "B" "B" "B" "B" "B" "B" "A" "A" "A"
#>  [ reached getOption("max.print") -- omitted 224 entries ]
#> 
#> [[6]]
#>  [1] 2 2 2 2 2 2 2 1 1 1
#>  [ reached getOption("max.print") -- omitted 224 entries ]

Created on 2024-09-20 with reprex v2.1.1

EDIT: It should work with a plain data.frame even.

library(ggplot2)

pal_dataframe <- function(values) {
  force(values)
  function(n) {
    n_values <- vctrs::vec_size(values)
    if (n > n_values) {
      cli::cli_warn("Don't do this")
    }
    vctrs::vec_slice(values, seq_len(n))
  }
}

df <- data.frame(foo = LETTERS[1:3], bar = 1:3)
rownames(df) <- c("r", "4", "f")

p <- ggplot(mpg, aes(displ, hwy, colour = drv)) +
  geom_point() +
  discrete_scale(
    "colour", palette = pal_dataframe(df)
  )

options(max.print = 10)
head(layer_data(p)$colour)
#> Error in `[.data.frame`(pal, match(as.character(x), names(pal))): undefined columns selected

Created on 2024-09-20 with reprex v2.1.1

teunbrand commented 3 hours ago

Oops posted this in the wrong repository, I apologise so much!