`labeller` with `facet_grid` seems to remove formatting

I have a figure I'm trying to make with facet_grid where the labels for the rows and columns are numerical. I'd like to add a thousands place comma for the big numbers on the rows and trailing zeros for fractional values on the columns. There's also some text that gets inserted into the label. Although I make the functions and additional text shows up on the plot, the comma and trailing zeros get removed. If I run the functions on a specific value, it gets formatted correctly...

library(tidyverse)

add_comma <- function(x){
  paste("N = ", format(x, big.mark = ",") ) 
}

add_zeros <- function(x){
  paste("F = ", format(x, nsmall = 2L))  
}

numbers <- rep(c(1e3, 2e4, 4e4, 1e4), 25)
decimals <- rep(seq(1, 2, by=0.25), 20)

x <- runif(100)
y <- runif(100)

tibble(numbers = numbers, decimals = decimals, x=x, y=y) %>%
  ggplot(aes(x = x, y = y)) +
  geom_point() +
  facet_grid(numbers ~ decimals,
             labeller = labeller(numbers = add_comma,
                                 decimals = add_zeros))

If I do add_comma(10000), I get "N = 10,000" and if I do add_zeros(1), I get "F = 1.00". So those functions seem to be working correctly. I'm sure I could use something like mutate to change the labels directly (maybe?), but it seems like this should work, but it isn't.

Ideas?

R version 4.2.2 (2022-10-31)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] forcats_0.5.2   stringr_1.4.1   dplyr_1.0.10    purrr_0.3.5     readr_2.1.3     tidyr_1.2.1    
[7] tibble_3.1.8    ggplot2_3.3.6   tidyverse_1.3.2

loaded via a namespace (and not attached):
 [1] pillar_1.8.1        compiler_4.2.2      cellranger_1.1.0    dbplyr_2.2.1        tools_4.2.2        
 [6] digest_0.6.30       lubridate_1.8.0     jsonlite_1.8.4      googledrive_2.0.0   lifecycle_1.0.3    
[11] gargle_1.2.1        gtable_0.3.1        pkgconfig_2.0.3     rlang_1.0.6         reprex_2.0.2       
[16] DBI_1.1.3           cli_3.4.1           rstudioapi_0.14     haven_2.5.1         xml2_1.3.3         
[21] withr_2.5.0         httr_1.4.4          generics_0.1.3      vctrs_0.5.0         fs_1.5.2           
[26] hms_1.1.2           googlesheets4_1.0.1 grid_4.2.2          tidyselect_1.2.0    glue_1.6.2         
[31] R6_2.5.1            fansi_1.0.3         readxl_1.4.1        farver_2.1.1        tzdb_0.3.0         
[36] modelr_0.1.10       magrittr_2.0.3      ellipsis_0.3.2      backports_1.4.1     scales_1.2.1       
[41] rvest_1.0.3         assertthat_0.2.1    colorspace_2.0-3    labeling_0.4.2      utf8_1.2.2         
[46] stringi_1.7.8       munsell_0.5.0       broom_1.0.1         crayon_1.5.2       

According to the documentation, labeller() can be passed a function taking and returning character vectors. I suppose this means the numeric vectors being passed to the functions become character vectors. Therefore, wrapping x in as.numeric() in both of your functions achieves the desired output.

library(tidyverse)

add_comma <- function(x){
  paste("N = ", format(as.numeric(x), big.mark = ",") ) 
}

add_zeros <- function(x){
  paste("F = ", format(as.numeric(x), nsmall = 2L))  
}

numbers <- rep(c(1e3, 2e4, 4e4, 1e4), 25)
decimals <- rep(seq(1, 2, by=0.25), 20)

x <- runif(100)
y <- runif(100)

tibble(numbers = numbers, decimals = decimals, x=x, y=y) %>%
  ggplot(aes(x = x, y = y)) +
  geom_point() +
  facet_grid(numbers ~ decimals,
             labeller = labeller(numbers = add_comma,
                                 decimals = add_zeros))

image

Created on 2023-03-07 with reprex v2.0.2.9000

3 Likes

Brilliant - thank you! I guess that also helps me make sense of what the deprecated keep.as.numeric argument did.

Pat

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.