Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

no visible global function definition for ':='

Tags:

r

tidyeval

I am writing a package that uses tidyeval. Becuase I use tidyeval I have rlang listed under imports in the description file.

One of the functions contains a few lines that use :=

Like this:

data %>%
    dplyr::mutate(
      !!New_R := AP_R_X*!!X + AP_R_Y*!!Y + AP_R_Z*!!Z,
      !!New_U := AP_U_X*!!X + AP_U_Y*!!Y + AP_U_Z*!!Z,
      !!New_F := AP_F_X*!!X + AP_F_Y*!!Y + AP_F_Z*!!Z) 

The code works as intended but I get the following note when running devtools::check()

 no visible global function definition for ':='

How can I get rid of this note? Is this not a part of rlang evaluation?


EDIT: I have read the question "no visible global function definition for ‘median’, although the answers there explain why such a problem can arise. It does not explain why := is not defined when I have imported rlang. I have edited the question to make this more clear.

like image 958
Steen Harsted Avatar asked Sep 20 '19 10:09

Steen Harsted


People also ask

Is there any visible binding for global variable ‘?

no visible binding for global variable ‘.’ 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.

Does my_FN have any binding for the global variable hp?

NOTE my_fn: no visible binding for global variable ‘mpg_div_hp’ my_fn: no visible binding for global variable ‘mpg’ my_fn: no visible binding for global variable ‘hp’ Undefined global functions or variables: hp mpg mpg_div_hp

How to avoid undefined global variables when programming with dplyr?

When programming with dplyr, what is the correct way to avoid undefined global variables? You can put the following R code somewhere in your package, perhaps an R/globals.R script. I see this has been solved but here is a dplyr / rlang specific suggestion: you can use the .data pronoun cf this dplyr vignette,


1 Answers

After you updated your answer, to me, this is sort of on the line of whether it's a full duplicate or not. The only difference here is that you've added rlang to Imports in DESCRIPTION and haven't seen the difference between that and a NAMESPACE directive.

I mocked up an example package to show this isn't sufficient. First, I set up the package:

library(devtools)
create("anExample", rstudio = FALSE, open = FALSE)

Then, I add the example function from https://dplyr.tidyverse.org/articles/programming.html to a file R/my_mutate.R:

#' A function
#'
#' @param df A dataframe
#' @param expr A variable in the dataframe
#'
#' @return The dataframe with new mean and sum columns
#' @export
my_mutate <- function(df, expr) {
    expr <- enquo(expr)
    mean_name <- paste0("mean_", quo_name(expr))
    sum_name <- paste0("sum_", quo_name(expr))

    mutate(df,
           !! mean_name := mean(!! expr),
           !! sum_name := sum(!! expr)
    )
}

Notice there are no roxygen2 namespace tags. I make sure to add rlang and dplyr to Imports in DESCRIPTION and run devtools::document(). Then when I run devtools::check() I get the following:

my_mutate: no visible global function definition for ‘enquo’
  my_mutate: no visible global function definition for ‘quo_name’
  my_mutate: no visible global function definition for ‘mutate’
  my_mutate: no visible global function definition for ‘:=’
  Undefined global functions or variables:
    := enquo mutate quo_name

0 errors ✔ | 1 warning ✖ | 1 note ✖

However, if I change R/my_mutate.R to the following:

#' A function
#'
#' @param df A dataframe
#' @param expr A variable in the dataframe
#'
#' @return The dataframe with new mean and sum columns
#' @importFrom dplyr mutate
#' @importFrom rlang enquo
#' @importFrom rlang quo_name
#' @importFrom rlang :=
#' @export
my_mutate <- function(df, expr) {
    expr <- enquo(expr)
    mean_name <- paste0("mean_", quo_name(expr))
    sum_name <- paste0("sum_", quo_name(expr))

    mutate(df,
           !! mean_name := mean(!! expr),
           !! sum_name := sum(!! expr)
    )
}

When I run devtools::check() (after re-document()ing), I do not get that note.

Long story short, Import in DESCRIPTION is not sufficient. You also need NAMESPACE directives.

like image 81
duckmayr Avatar answered Sep 19 '22 07:09

duckmayr