Home > Software design >  Using get() to retrieve functions from a package that is not loaded
Using get() to retrieve functions from a package that is not loaded

Time:09-09

I can use get to access functions, like so:

get("sum")
# function (..., na.rm = FALSE)  .Primitive("sum")

If I want to get a function from a package, I can load the package and then get the function:

library(data.table)
get("uniqueN")

# function (x, by = if (is.list(x)) seq_along(x) else NULL, na.rm = FALSE) 
# {
#   if (is.null(x)) 
#     return(0L)
#   if (!is.atomic(x) && !is.data.frame(x)) 
#     stop("x must be an atomic vector or data.frames/data.tables")
#   if (is.atomic(x)) {
#     if (is.logical(x)) 
#       return(.Call(CuniqueNlogical, x, na.rm = na.rm))
#     x = as_list(x)
#   }
#   o = forderv(x, by = by, retGrp = TRUE, na.last = if (!na.rm) 
#     FALSE
#     else NA)
#   starts = attr(o, "starts", exact = TRUE)
#   if (!na.rm) {
#     length(starts)
#   }
#   else {
#     sum((if (length(o)) o[starts] else starts) != 0L)
#   }
# }
# <bytecode: 0x5559622e2f60>
#   <environment: namespace:data.table>

Now, say I want to do this without loading the package. My initial thought was,

get("data.table::uniqueN")
# Error in get("data.table::uniqueN") : 
#   object 'data.table::uniqueN' not found

Clearly, that doesn't work. Within get, I can specify the environment where to look for the object (i.e., with the envir parameter), but as the package is not loaded presumably there isn't a package environment yet.


Question: How do I get a function from a package that isn't loaded?

CodePudding user response:

get has an envir argument, and you can obtain the namespace of a package via getNamespace without attaching it to the search path, so one option is:

get("uniqueN", envir = getNamespace('data.table'))
#> function (x, by = if (is.list(x)) seq_along(x) else NULL, na.rm = FALSE) 
#> {
#>     if (is.null(x)) 
#>         return(0L)
#>     if (!is.atomic(x) && !is.data.frame(x)) 
#>         stop("x must be an atomic vector or data.frames/data.tables")
#>     if (is.atomic(x)) {
#>         if (is.logical(x)) 
#>             return(.Call(CuniqueNlogical, x, na.rm = na.rm))
#>         x = as_list(x)
#>     }
#>     o = forderv(x, by = by, retGrp = TRUE, na.last = if (!na.rm) 
#>         FALSE
#>     else NA)
#>     starts = attr(o, "starts", exact = TRUE)
#>     if (!na.rm) {
#>         length(starts)
#>     }
#>     else {
#>         sum((if (length(o)) o[starts] else starts) != 0L)
#>     }
#> }
#> <bytecode: 0x000001c545c5e208>
#> <environment: namespace:data.table>
  •  Tags:  
  • r
  • Related