Undefined global functions or variables: :=

Stupid question:

I have a package which uses the line

dplyr::mutate(!!rlang::sym(column) :=
                    ifelse(!!rlang::quo(Anonymous),
                           -1,
                           !!!rlang::sym(column))) %>%

and it provides exactly the results I want. But when I run CHECK, I get back this NOTE:

getUserDropdownSafetyObservation: no visible global function definition for ':='
Undefined global functions or variables: :=

What's the trick to rectifying this note without use of globalVariables? I tried searching for solutions for about 20 minutes, but ":=" doesn't seem to be a very good search term.

:= is a left-over assignment symbol from earlier R/S days. Be default it currently has no implementation. Packages such as data.table, and wrapr define their own versions, but these are not available until you call library(pkg). I think dplyr just uses the presence of the symbol in unparsed expressions (so does not need an actual implementation) and currently does not export :=.

I think you can get around the check with something like the following (just loose in your package, and don't bother to export it).

`:=` <- function(a,b) {stop(":= should not be called directly")}

Then code such as the following still works (as dplyr either uses its own package definition, or more likely never executes the user code in the first place).

dplyr::mutate(data.frame(x = 1:2), y := x + 1)

The above is safe code, and turns off a minimum number of checks.

By the way wrapr defines := as assigning names, which is very close to how a user sees := being used in other packages. For example.

rm(list = ":=")
library("wrapr")
c("name1", "name2") := c(1, 2)

# name1 name2 
#     1     2 
1 Like

The := is defined in rlang, however, and is cited for use

!! mean_name = mean(!! expr) isn’t valid R code, so we need to use the := helper provided by rlang.
(Programming with dplyr • dplyr)

You also get the help file through ?rlang::':='. But I haven't yet figured out how to access that operator without generating the NOTE above.

EDIT:

Nevermind. Adding @importFrom rlang := to my documentation was what I was missing.

4 Likes

Another option is to use utils::globalVariables() to declare the symbol. Importing the operator from rlang has the advantage that if you use := in a wrong place you will get an informative error. We unfortunately don't have this luxury with !! as it is not a real operator.

4 Likes