Using a quasiquoted argument to a function within a purrr:map call

237 views Asked by At

I'm having a little trouble figuring out quasiquotation, specifically I have a function which takes an argument which specifies which variable should go into a model which is then run within a purrr::map call.

I've been working from: https://dplyr.tidyverse.org/articles/programming.html

# libs
library(tidyverse)
library(broom)
# dummy data
df <- data.frame(
    "a"=rep(c("alpha","beta"),50),
    "b"=rnorm(100),
    "value1"=rnorm(100),
    "value2"=rnorm(100)
)

model <- function(var) {
    var <- enquo(var)
    df %>%
        group_by(a) %>%
        nest() %>%
        mutate(model=map(data, ~ lm(b ~ (!! var),data=.)))
}

model(value1)

> Error in mutate_impl(.data, dots) : Evaluation error: invalid model formula.

putting the name in directly works as expected:

df %>%
    group_by(a) %>%
    nest() %>%
    mutate(model=map(data, ~ lm(b ~ value1,data=.))) %>%
    unnest(model %>% map(glance))

I can use !! var within a function:

modelX <- function(var,df=df) {
    var <- enquo(var)
    df %>%
        select(!! var)
}

modelX(value1,df) 

I'm assuming that this has something to do with the fact the !! var is referring to a value in the nested tibble data, I've been poking around with rlang::qq_show() but haven't been able to figure it out so far'

1

There are 1 answers

0
MrFlick On BEST ANSWER

The enquo() will attempt to track the enviroment of the symbol you pass in, but you don't really want that included in the formula you are passing to lm. It would be better to capture that as a symbol rather than a quosure. Try this

model <- function(var) {
  var <- ensym(var)
  df %>%
    group_by(a) %>%
    nest() %>%
    mutate(model=map(data, ~ lm(b ~ !!var, data=.)))
}

Worked for me with dplyr_0.7.6 and purrr_0.2.5