Using the .data pronoun in anonymous function

Hi All,

I cannot seem to figure out what is the problem with using the .data pronoun in an anonymous function. If I save the function separately it works.

Can you point me in the right direction?

Here is a reprex:

iris_plots <-
  tibble(
    vars = c("Sepal.Length", "Sepal.Width", "Petal.Length"),
    plot = map(vars, function(my_var) {
      iris %>% 
        ggplot() +
        aes(x = .data[[my_var]]) +
        geom_histogram()
    })
  )

my_plot <- function(my_var) {
  iris %>% 
    ggplot() +
    aes(x = .data[[my_var]]) +
    geom_histogram()
}

iris_plots <-
  tibble(
    vars = c("Sepal.Length", "Sepal.Width", "Petal.Length"),
    plot = map(vars, ~ my_plot(my_var = .x))
  )

iris_plots$plot

I don't have a complete answer for you but I can show some things perhaps.

.data can be used in an anonymous function :

vars <- c("Sepal.Length", "Sepal.Width", "Petal.Length")
    p <- map(vars, function(my_var) {
      iris %>% 
        ggplot() +
        aes(x = .data[[my_var]]) +
        geom_histogram()
    })

The difference between this and your original is that there is not a context of making a tibble ; I think its therefore something in how the tibble is constructed.

1 Like

(That's not a reprex, by the way.)

This might be useful, as might this and this

Here's some more playing around with this that I've done:

library(tidyverse)

# This doesn't quite give you the output you suggest, but it shows how the `.data` pronoun can be used in an anonymous function
vars <- c("Sepal.Length", "Sepal.Width", "Petal.Length")

plots <- map(vars, function(var) { 
  iris %>% ggplot(aes(x = .data[[var]])) + geom_histogram()
})

# however it doesn't seem to work well within the tibble structure you suggest
iris_plots <-
  tibble(
    vars = vars,
    plots = map(vars, function(var) { 
      iris %>% ggplot(aes(x = .data[[var]])) + geom_histogram()
    })
  )

iris_plots$plots
#> [[1]]
#> Error: Unknown input: function

# I thought it might work better with `mutate`, but no
iris_plots <-
  tibble(
    vars = vars) %>% 
  mutate(plots = across(vars, function(var) { 
      iris %>% ggplot(aes(x = .data[[var]])) + geom_histogram()
    })
  )
#> Error: Problem with `mutate()` column `plots`.
#> i `plots = across(...)`.
#> x Input must be a vector, not a <gg/ggplot> object.

# however you can just make your tibble like this:
iris_plots <-
  tibble(
    vars = vars,
    plots = plots
  )

iris_plots$plots
#> [[1]]
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

#> 
#> [[2]]
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

#> 
#> [[3]]
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Created on 2021-10-04 by the reprex package (v2.0.1)

1 Like

damn, you beat me to it - I spent too long playing about trying to make it work!

Doing map on the outside and tibble construction on the inside seems a happy option also


p1 <- map_dfr(c("Sepal.Length", "Sepal.Width", "Petal.Length"), ~ {
tibble(vars=.x, plot = list(iris %>% 
    ggplot() +
    aes(x = .data[[.x]]) +
    geom_histogram()))})

p2 <- map_dfr(c("Sepal.Length", "Sepal.Width", "Petal.Length"), function(x) {
  tibble(vars=x, plot = list(iris %>% 
                                ggplot() +
                                aes(x = .data[[x]]) +
                                geom_histogram()))})
2 Likes

Interesting solution. Using tibble() on the outside would help the readability, but this is at least working. Thanks!

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.