我有一个包含自定义方法的包summary()
,print()
用于具有特定类的对象。这个包还使用了出色的dplyr
包进行数据操作——我希望我的用户编写使用我的包和 dplyr 的脚本。
其他人在这里和这里已经注意到的一个障碍是 dplyr 动词不保留自定义类 - 这意味着ungroup
命令可以剥离我的 data.frames 他们的自定义类,从而搞砸了方法调度summary
等。
Hadley 说“正确地执行此操作取决于您 - 您需要为每个 dplyr 方法为您的类定义一个方法,以正确恢复所有类和属性”,我正在尝试接受建议- 但我无法弄清楚如何正确包装 dplyr 动词。
这是一个简单的玩具示例。假设我已经定义了一个cars
类,并且我对它有一个自定义summary
。
这行得通
library(tidyverse)
class(mtcars) <- c('cars', class(mtcars))
summary.cars <- function(x, ...) {
#gather some summary stats
df_dim <- dim(x)
quantile_sum <- map(mtcars, quantile)
cat("A cars object with:\n")
cat(df_dim[[1]], 'rows and ', df_dim[[2]], 'columns.\n')
print(quantile_sum)
}
summary(mtcars)
这就是问题所在
small_cars <- mtcars %>% filter(cyl < 6)
summary(small_cars)
class(small_cars)
该summary
调用small_cars
只是给了我通用摘要,而不是我的自定义方法,因为在 dplyr 过滤后small_cars
不再保留该类。cars
我试过的
filter
首先,我尝试围绕( )编写自定义方法filter.cars
。那没有用,因为实际上是一个允许非标准评估filter
的包装器。filter_
所以我filter_
为对象编写了一个自定义方法cars
,试图实现@jwdink 的建议
filter_.cars <- function(df, ...) {
old_classes <- class(df)
out <- dplyr::filter_(df, ...)
new_classes <- class(out)
class(out) <- c(new_classes, old_classes) %>% unique()
out
}
这不起作用 - 我得到一个无限递归错误:
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Error during wrapup: evaluation nested too deeply: infinite recursion / options(expressions=)?
我要做的就是获取传入 df 上的类,移交给 dplyr,然后返回具有与 dplyr 调用之前相同的类名的对象。 我如何更改我的filter_
包装器来实现这一点? 谢谢!