3

I am writing a package using a lot of dplyr functions - to pass on all tests in devtools::check(), I have to use .data frequently. Some of the functions are nested into other functions. In the example below, I need to use variable both in a tidyselect context and in standard evaluation (in the part that creates id).

df <- data.frame(
  V1 = 1:8,
  V2 = rep(1:4,2)
)

test <- function(df, variable){
  
  x <- df %>%
    mutate(y = {{variable}} + 1)

  id <- rlang::as_name(rlang::enquo(variable))
  
  id_eq <- outer(df[[id]], df[[id]], `==`)
  
  list(x, id_eq)
}

I don't know how to deal with this without getting any warnings or notes in CMD check. The function works if I run test(df = df, variable = V1), but not with test(df = df, variable = .data$V1)

  • Hi Arthur, the general intuition behind `.data` and `.env` is to [disambiguate whether the name refers to a column in a data frame or a variable in the environment](https://tinyheero.github.io/2020/03/01/use-data-env-pronouns-tidyverse.html). However, it is a bit unclear how your function should behave with `.env$V1`. The `mutate()` statement is obvious, but what should happen in the `outer()` statement when the user supplies `.env$myvar`? – Artem Sokolov Nov 30 '20 at 19:14
  • @ArtemSokolov that is my point, I was looking for a way so that the user supplies ```variable``` in a way that passes ```devtools::check()``´ at the same time that this variable could either work in the ```outer``` part (e.g ```outer(df[['V1']], df[['V1']], `==`)``` or inside ```mutate``` – Arthur Carvalho Brito Nov 30 '20 at 19:18

1 Answers1

1

One option is to let tidyverse do the work of finding the correct variable. Store the output of this work into a temporary variable, and use that variable throughout your function:

test <- function(df, variable){

    tmp <- df %>% mutate( .tmp = {{variable}} ) %>% pull(.tmp)

    x <- df %>%
        mutate(y = tmp + 1)

    id_eq <- outer(tmp, tmp, `==`)

    list(x, id_eq)
}

The function works with all sensible variable references, including .data and .env pronouns:

test( df, V1 )
test( df, .data$V1 )

V1 <- 11:18
test( df, .env$V1 )
Artem Sokolov
  • 13,196
  • 4
  • 43
  • 74
  • thank you! What about in a context in which I need to subset the data, as in ```id_eq <- df[[1:3, variable]]```. How can I adapt this so that it works? It would also be nested in a function like the one in the question – Arthur Carvalho Brito Nov 30 '20 at 20:00
  • @ArthurCarvalhoBrito Would `id_eq <- tmp[1:3]` not do the trick? Maybe I'm missing the big picture. – Artem Sokolov Nov 30 '20 at 20:29