扩展 tibble:让新的 S3 class 坚持下去
Extending tibble: getting the new S3 class to stick
对于ropensci/drake#489, I would like to define a new print method for tibbles
of class "drake_plan"
. I read the guide on extending tibble
,这对某些需求很有帮助。但是新的 "drake_plan"
S3 class 在 dplyr
操作期间掉落。
#' @title Mark a data frame as a `drake` workflow plan
#' @description Used for pretty printing only (coming soon).
#' You do not actually have to mark plans as such.
#' You can keep them as ordinary data frames.
#' @export
#' @keywords internal
#' @param x object to mark as a `drake` plan
#' @param ... other arguments to the method
#' @examples
#' plan <- list(target = "x", command = "get_data()")
#' class(plan)
#' plan <- as_drake_plan(plan)
#' class(plan)
as_drake_plan <- function(x){
UseMethod("as_drake_plan")
}
as_drake_plan_ <- function(x, ...){
tibble::new_tibble(x, ..., subclass = "drake_plan")
}
#' @export
`[.drake_plan` <- function(...){
as_drake_plan_(NextMethod())
}
#' @export
#' @rdname as_drake_plan
as_drake_plan.data.frame <- as_drake_plan_
#' @export
#' @rdname as_drake_plan
as_drake_plan.list <- as_drake_plan_
#' @export
#' @rdname as_drake_plan
as_drake_plan.tbl_df <- as_drake_plan_
library(dplyr)
library(drake)
plan <- drake_plan(
x = get_data(),
y = analyze_data(x)
) %>%
as_drake_plan() %>%
print
#> # A tibble: 2 x 2
#> target command
#> * <chr> <chr>
#> 1 x get_data()
#> 2 y analyze_data(x)
class(plan)
#> [1] "drake_plan" "tbl_df" "tbl" "data.frame"
filter(plan, target == "x") %>%
class()
#> [1] "tbl_df" "tbl" "data.frame"
除了dplyr
函数之外,是否还有其他情况可以从tibble
s中移除subclasses?
我刚刚发现这已经记录在 dplyr
开发页面上:https://github.com/tidyverse/dplyr/issues/2532。显然,没有计划尝试保留 tibble
个子类。
tibble
包现在有一个 new_tibble()
构造函数,@landau 也指出了这一点:
https://tibble.tidyverse.org/reference/new_tibble.html
# The nrow argument is always required:
new_tibble(list(a = 1:3, b = 4:6), nrow = 3)
#> # A tibble: 3 x 2
#> a b
#> <int> <int>
#> 1 1 4
#> 2 2 5
#> 3 3 6
对于ropensci/drake#489, I would like to define a new print method for tibbles
of class "drake_plan"
. I read the guide on extending tibble
,这对某些需求很有帮助。但是新的 "drake_plan"
S3 class 在 dplyr
操作期间掉落。
#' @title Mark a data frame as a `drake` workflow plan
#' @description Used for pretty printing only (coming soon).
#' You do not actually have to mark plans as such.
#' You can keep them as ordinary data frames.
#' @export
#' @keywords internal
#' @param x object to mark as a `drake` plan
#' @param ... other arguments to the method
#' @examples
#' plan <- list(target = "x", command = "get_data()")
#' class(plan)
#' plan <- as_drake_plan(plan)
#' class(plan)
as_drake_plan <- function(x){
UseMethod("as_drake_plan")
}
as_drake_plan_ <- function(x, ...){
tibble::new_tibble(x, ..., subclass = "drake_plan")
}
#' @export
`[.drake_plan` <- function(...){
as_drake_plan_(NextMethod())
}
#' @export
#' @rdname as_drake_plan
as_drake_plan.data.frame <- as_drake_plan_
#' @export
#' @rdname as_drake_plan
as_drake_plan.list <- as_drake_plan_
#' @export
#' @rdname as_drake_plan
as_drake_plan.tbl_df <- as_drake_plan_
library(dplyr)
library(drake)
plan <- drake_plan(
x = get_data(),
y = analyze_data(x)
) %>%
as_drake_plan() %>%
print
#> # A tibble: 2 x 2
#> target command
#> * <chr> <chr>
#> 1 x get_data()
#> 2 y analyze_data(x)
class(plan)
#> [1] "drake_plan" "tbl_df" "tbl" "data.frame"
filter(plan, target == "x") %>%
class()
#> [1] "tbl_df" "tbl" "data.frame"
除了dplyr
函数之外,是否还有其他情况可以从tibble
s中移除subclasses?
我刚刚发现这已经记录在 dplyr
开发页面上:https://github.com/tidyverse/dplyr/issues/2532。显然,没有计划尝试保留 tibble
个子类。
tibble
包现在有一个 new_tibble()
构造函数,@landau 也指出了这一点:
https://tibble.tidyverse.org/reference/new_tibble.html
# The nrow argument is always required:
new_tibble(list(a = 1:3, b = 4:6), nrow = 3)
#> # A tibble: 3 x 2
#> a b
#> <int> <int>
#> 1 1 4
#> 2 2 5
#> 3 3 6