Home > front end >  Why do.call cannot locate an enlisted function?
Why do.call cannot locate an enlisted function?

Time:08-20

PREMISE: I am trying to debug this:

https://github.com/masurp/specr/issues/29

I located the error in a function

map2(x,y,~do.call(.x,list(df,.y))

REPRODUCIBLE ISSUE:

df = tibble(y = rnorm(100),
            x = rnorm(100)
            )

model = list()

lm -> LM
lm -> model$LM

LM and model$LM should be equivalent, however,

this code works:

specr:::setup_specs(y = "y",
            x = "x",
            model = "LM"
) %>%
  dplyr::mutate(formula = pmap(.,
                               specr:::create_formula)
  ) %>% tidyr::unnest(formula) %>%
  dplyr::mutate(res = map2(.data$model,
                           formula,
                           ~do.call(.x,
                                    list(data = df,
                                         formula = .y))))

The same exact code don't if the param model="model$LM"

specr:::setup_specs(y = "y",
            x = "x",
            model = "model$LM"
) %>%
  dplyr::mutate(formula = pmap(.,
                               specr:::create_formula)
  ) %>% tidyr::unnest(formula) %>%
  dplyr::mutate(res = map2(.data$model,
                           formula,
                           ~do.call(.x,
                                    list(data = df,
                                         formula = .y))))

The error:

Error in `dplyr::mutate()`:
! Problem while computing `res = map2(.data$model,
  formula, ~do.call(.x, list(data = df, formula = .y)))`.
Caused by error in `model$LM`:
! could not find function "model$LM"

CodePudding user response:

I suggest using a helper function get_model which checks if the string is an bare object name or a call and in the latter case it returns it in its evaluated form.

library(dplyr)
library(purrr)
library(specr)

# data used from question post

get_model <- function(x) {
  x_str <- str2lang(x)
  if (is.name(x_str)) {
    return(x)
    } else if (is.call(x_str)) {
    eval(x_str)
  }
}

specr:::setup_specs(y = "y",
                    x = "x",
                    model = "LM"
) %>%
  dplyr::mutate(formula = pmap(.,
                               specr:::create_formula)
  ) %>% tidyr::unnest(formula) %>% 
  dplyr::mutate(res = map2(model,
                           formula,
                           ~ do.call(get_model(.x), list(data = df, formula = .y))))
#> # A tibble: 1 x 6
#>   x     y     model controls      formula   res   
#>   <chr> <chr> <chr> <chr>         <chr>     <list>
#> 1 x     y     LM    no covariates y ~ x   1 <lm>


specr:::setup_specs(y = "y",
                    x = "x",
                    model = "model$LM"
) %>%
  dplyr::mutate(formula = pmap(.,
                               specr:::create_formula)
  ) %>% tidyr::unnest(formula) %>%
  dplyr::mutate(res = map2(.data$model,
                           formula,
                           ~ do.call(get_model(.x), list(data = df, formula = .y))))
#> # A tibble: 1 x 6
#>   x     y     model    controls      formula   res   
#>   <chr> <chr> <chr>    <chr>         <chr>     <list>
#> 1 x     y     model$LM no covariates y ~ x   1 <lm>

Created on 2022-08-19 by the reprex package (v2.0.1)

  • Related