Issues when defining methods for `[` and `[[` in a package

Viewed 61

I have the following method part of a package (the code itself is not important):

#' Improved vector subsetting
#'
#' @param x a composer_vector
#' @param i standard indices used to subset
#' @param ... predicate subsetting functions applied on top off subset by indices
#' @export
#' @examples
#' vec <- co("A hello", "B hi")
#' vec[,~startsWith(.,"A")]
#' vec[1:2, ~startsWith(.,"A")]
#' vec[startsWith ="A"]
`[.composer_vector` <- function(x, i, ...) {
  x  <- unco(x)
  if (!missing(i)) x <- x[i]
  fs  <- list(...)
  if (length(fs)) {
    fs <- harmonize_funs(fs,NULL)
    x <- x[purrr::reduce(fs,~.y(x) & .x, .init = TRUE)]
  }
  co(x)
}

I can document, build and install the package without issue, using:

devtools::document()
pkg_path  <- devtools::build()
install.packages(pkg_path, repos = NULL, type="source",clean=TRUE)

but when I attach the package, the method is not exported (not accessible with ::, though accessible with :::), and is not called when I use it on an object of the appropriate class.

If I rename it to foo all goes well and foo is exported.

I have the same issue when defining a method for [[.

If it works for data.table , why doesn't it work for me?


the full package code is on github and this code in particular is located in brackets.R

1 Answers

It's because the function is not exported in your NAMESPACE file. The @export tag will only help you with your NAMESPACE file if it does not exist when you run devtools::document(); if you already have a NAMESPACE file when you document(), you'll get the warning

Warning: The existing 'NAMESPACE' file was not generated by roxygen2, and will not be overwritten.

Your NAMESPACE has

exportPattern("^[[:alpha:]]+")

This is normally fine, because usually you only have functions (that you want exported) that begin with a letter. However, here you want functions exported that begin with [, which this will not do. So, if you delete your NAMESPACE file and re-run devtools::document("composer/"), and reinstall the package, a new NAMESPACE will be written that properly exports all functions, including your extract methods:

# Generated by roxygen2: do not edit by hand

S3method("[",composer_vector)
S3method("[[",composer_vector)
export(..)
export(co)
export(compose2)
export(unco)

Then the following works just fine:

library(composer)

vec <- co("A hello", "B hi")
vec[,~startsWith(.,"A")]

# [1] "A hello"
# attr(,"class")
# [1] "composer_vector" "character"      

vec[startsWith ="A"]

# [1] "A hello"
# attr(,"class")
# [1] "composer_vector" "character"      
Related