Extending dplyr::filter in a package

I'm developing a package that includes extending dplyr verbs for a specific class. Basically it's just a lit of data frames that have fixed column names.

The problem is that devtools::check() gives me the following warning:

"declared S3 method 'filter.df_list' not found"

I don't get this warning with any of the other dplyr verbs, plus the method actually works as expected in the package examples. I'm wondering if this warning is something do with stats::filter existing as well? However, I can't figure out how I would deal with that, so any advice would be greatly appreciated!

A minimal version of the package code is below:

#' Create a df_list list
#'
#' @param l a list of data frames
#'
#' @return a list of data frames with class df_list
#' @export
#'
#' @examples
#' as_df_list(list(a = mtcars, b = mtcars))

as_df_list <- function(l) {
  if (is.data.frame(l)) {
    return(structure(list(df = l), class = "df_list"))
  }
  if (is.list(l) && all(sapply(l, is.data.frame))) {
    return(structure(l, class = "df_list"))
  }
  stop("l must be a data frame or list of data frames.")
}

#' Filter data frames in a list
#'
#' See \link[dplyr]{filter}
#'
#' @inheritParams dplyr::filter
#' @importFrom dplyr filter
#'
#' @return A list of filtered data frames
#' @export
#'
#' @examples
#' library(dplyr)
#' filter(
#'   as_df_list(list(a = mtcars, b = mtcars)),
#'   cyl == 4
#' )

filter.df_list <- function(.data, ...) {
  as_df_list(lapply(.data, filter, ...))
}

#' Modify or create columns for data frames in a list
#'
#' See \link[dplyr]{mutate}
#'
#' @inheritParams dplyr::mutate
#' @importFrom dplyr mutate
#'
#' @return A list of mutated data frames
#' @export
#'
#' @examples
#' library(dplyr)
#' mutate(
#'   as_df_list(list(a = mtcars, b = mtcars)),
#'   lp100km = 235.214538 / mpg
#' )
mutate.df_list <- function(.data, ...) {
  as_df_list(lapply(.data, mutate, ...))
}

#' @rdname mutate.df_list
#' @importFrom dplyr transmute
#' @export
#' @examples
#' library(dplyr)
#' transmute(
#'   as_df_list(list(a = mtcars, b = mtcars)),
#'   cyl, mpg, lp100km = 235.214538 / mpg
#' )
transmute.df_list <- function(.data, ...) {
  as_df_list(lapply(.data, transmute, ...))
}

#' Select columns from data frames in a list
#'
#' See \link[dplyr]{select}
#'
#' @inheritParams dplyr::select
#' @importFrom dplyr select
#'
#' @return A list of data frames with the selected columns
#' @export
#'
#' @examples
#' library(dplyr)
#' select(
#'   as_df_list(list(a = mtcars, b = mtcars)),
#'   cyl, mpg
#' )
select.df_list <- function(.data, ...) {
  as_df_list(lapply(.data, select, ...))
}

#' Rename columns of data frames in a list
#'
#' See \link[dplyr]{rename}
#'
#' @inheritParams dplyr::rename
#' @importFrom dplyr rename
#'
#' @return A list of data frames with renamed columns
#' @export
#'
#' @examples
#' library(dplyr)
#' rename(
#'   as_df_list(list(a = mtcars, b = mtcars)),
#'   num_cyl = cyl, horsepower = hp
#' )
rename.df_list <- function(.data, ...) {
  as_df_list(lapply(.data, rename, ...))
}

and the NAMESPACE file is this:

# Generated by roxygen2: do not edit by hand

S3method(filter,df_list)
S3method(mutate,df_list)
S3method(rename,df_list)
S3method(select,df_list)
S3method(transmute,df_list)
export(as_df_list)
importFrom(dplyr,filter)
importFrom(dplyr,mutate)
importFrom(dplyr,rename)
importFrom(dplyr,select)
importFrom(dplyr,transmute)

Hi, do you have a package with this code that we can try to run? If not, could you create one on GitHub or elsewhere?

I've made a basic package here

Seems like @davis figured this out:

You'll need to re-export dplyr::filter(), which is not great, but it is an OK workaround I guess.

A better alternative might be to implement a method for dplyr::dplyr_reconstruct(), which is used by a number of dplyr verbs and is often all you need to add to get full dplyr support for your class (depending on what it does).

I'd encourage you to read Extending dplyr with new data frame subclasses — dplyr_extending • dplyr too.

We typically encourage adding methods for these lower level functions first before adding methods for the "core" verbs like mutate() and friends, which is typically only needed for the most complicated cases.

Thanks! I'll just export dplyr::filter for now to suppress the warning, and then experiment with dplyr_reconstruct()and related functions in the longer term.

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.