gpt4 book ai didi

r - dplyr::do 内部函数的方法分派(dispatch)

转载 作者:行者123 更新时间:2023-12-04 10:08:16 26 4
gpt4 key购买 nike

如何为 dplyr::do 中的函数实现方法分派(dispatch)?

我已通读 GitHub 问题 #719 , #3558#3429其中包含有关如何为 dplyr 动词创建方法的有用信息,但没有什么特别适用于 dplyr::do - 从某种意义上说,这有点“特殊”调度不仅需要发生在 dplyr:do 本身,还需要发生在 dplyr::do 内部调用的函数(或者至少这就是我所追求的)

这是我尝试过的:

预赛

library(dplyr)
#>
#> Attache Paket: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union

# Example data ------------------------------------------------------------

df <- tibble::tibble(
id = c(rep("A", 5), rep("B", 5)),
x = 1:10
)

df_custom <- df
class(df_custom) <- c("tbl_df_custom", class(df_custom))

# Reclass function --------------------------------------------------------

reclass <- function(x, result) {
UseMethod('reclass')
}

reclass.default <- function(x, result) {
class(result) <- unique(c(class(x)[[1]], class(result)))
attr(result, class(x)[[1]]) <- attr(x, class(x)[[1]])
result
}

第 1 步:尝试为 dplyr 动词定义一个方法

# Custom method for summarize ---------------------------------------------

summarise.tbl_df_custom <- function (.data, ...) {
message("Custom method for `summarise`")
result <- NextMethod("summarise")
ret <- reclass(.data, result)
print(class(ret))
ret
}

ret <- df_custom %>%
summarise(y = mean(x))
#> Custom method for `summarise`
#> [1] "tbl_df_custom" "tbl_df" "tbl" "data.frame"
ret %>% class()
#> [1] "tbl_df_custom" "tbl_df" "tbl" "data.frame"

第 2 步:尝试为另一个 dplyr 动词定义一个方法来测试更长的管道

# Custom method for group_by ----------------------------------------------

group_by.tbl_df_custom <- function (.data, ..., add = FALSE) {
message("Custom method for `group_by`")
result <- NextMethod("group_by")
ret <- reclass(.data, result)
print(class(ret))
ret
}

ret <- df_custom %>%
group_by(id) %>%
summarise(y = mean(x))
#> Custom method for `group_by`
#> [1] "tbl_df_custom" "grouped_df" "tbl_df" "tbl"
#> [5] "data.frame"
#> Custom method for `summarise`
#> [1] "tbl_df_custom" "tbl_df" "tbl" "data.frame"
ret %>% class()
#> [1] "tbl_df_custom" "tbl_df" "tbl" "data.frame"

第 3 步:尝试对 do

进行相同操作
# Custom method for do ----------------------------------------------------

do.tbl_df_custom <- function (.data, ...) {
message("custom method for `do`")
result <- NextMethod("do")
ret <- reclass(.data, result)
print(class(ret))
ret
}

foo <- function(df) {
UseMethod("foo")
}

foo.default <- function(df) {
message("Default method for `foo`")
df %>%
summarise(y = mean(x))
}

foo.tbl_df_custom <- function(df) {
message("Custom method for `foo`")
df %>%
summarise(y = mean(x) * 100)
}

ret <- df_custom %>%
group_by(id) %>%
do(foo(.))
#> Custom method for `group_by`
#> [1] "tbl_df_custom" "grouped_df" "tbl_df" "tbl"
#> [5] "data.frame"
#> custom method for `do`
#> Default method for `foo`
#> Default method for `foo`
#> [1] "tbl_df_custom" "grouped_df" "tbl_df" "tbl"
#> [5] "data.frame"
ret
#> # A tibble: 2 x 2
#> # Groups: id [2]
#> id y
#> <chr> <dbl>
#> 1 A 3
#> 2 B 8
ret %>% class()
#> [1] "tbl_df_custom" "grouped_df" "tbl_df" "tbl"
#> [5] "data.frame"

虽然乍一看这看起来没问题,但问题是调用了 foodefault 而不是 custom 方法。

reprex package 创建于 2019-01-08 (v0.2.1)

最佳答案

所以这个问题与this question I just asked有关.我能够通过定义 3 个新函数来解决它:ungroup.tbl_df_custom,一个类构造函数,和 [.tbl_df_custom

ungroup.tbl_df_custom <- function (.data, ...) {
message("custom method for `ungroup`")
result <- NextMethod("ungroup")
ret <- reclass(.data, result)
ret
}


new_custom <- function(x, ...) {

structure(x, class = c("tbl_df_custom", class(x)))
}

`[.tbl_df_custom` <- function(x, ...) {
new_custom(NextMethod())
}



df_custom2 <- new_custom(df)


df_custom2 %>%
group_by(id) %>%
do(foo(.))

Custom method for `group_by`
[1] "tbl_df_custom" "grouped_df" "tbl_df" "tbl" "data.frame"
custom method for `do`
custom method for `ungroup`
Custom method for `foo`
Custom method for `summarise`
[1] "tbl_df_custom" "tbl_df" "tbl" "data.frame"
Custom method for `foo`
Custom method for `summarise`
[1] "tbl_df_custom" "tbl_df" "tbl" "data.frame"
[1] "tbl_df_custom" "grouped_df" "tbl_df" "tbl" "data.frame"
custom method for `ungroup`
# A tibble: 2 x 2
# Groups: id [2]
id y
<chr> <dbl>
1 A 300
2 B 800

关于r - dplyr::do 内部函数的方法分派(dispatch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54083208/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com