我正在嘗試調整一個長函式 ( rcompanion::groupwiseMean) 以使用dplyr而不是plyr::ddply在其代碼中使用,以避免依賴于現在已棄用的plyr包。
我想定義一個自定義ddply2函式,采用與原始函式相同的引數plyr,但dplyr在幕后。好處是只在現有長函式/腳本的頂部重新定義函式一次,而不更改任何其他內容。到目前為止,我的嘗試都失敗了。演示如下。
我一直在使用這個資源:plyr::ddply 等效于 dplyr
原始plyr:ddplyr通話
data <- mtcars
var <- "mpg"
group <- c("cyl", "am")
# Original plyr:ddply-fed function:
fun.y <- function(x, idx) { length(x[, idx]) }
# Original plyr:ddply call:
plyr::ddply(.data = data, .variables = group, var, .fun = fun.y)
#> cyl am V1
#> 1 4 0 3
#> 2 4 1 8
#> 3 6 0 4
#> 4 6 1 3
#> 5 8 0 12
#> 6 8 1 2
這是我無法重寫的功能
fun.y <- function(x, idx) { length(x[, idx]) }
然而,這只是一個例子。以下是我需要使用的其他一些功能ddply2:
fun.z <- function(x, idx) { as.numeric(mean(x[, idx], trim = trim, na.rm = na.rm)) }
fun.w <- function(x, idx) {
mean(boot(x[, idx], function(y, j) mean(y[j], trim = trim,
na.rm = na.rm), R = R, ...)$t[, 1])
}
現在讓我們繼續進行所需的ddply2呼叫,允許我以任何我想要的方式修改它。但是,它必須采用與 相同的引數plyr::ddply。
嘗試重寫plyr:ddply為dpply2
library(dplyr)
ddply2 <- function(.data, .variables, var, .fun) {
.data %>%
group_by(across({{.variables}})) %>%
do(.fun(., {{var}}))
}
ddply2(.data = data, .variables = group, var, .fun = fun.y)
# Error in `do()`:
# ! Results 1, 2, 3, 4, 5, 6 must be data frames, not integer.
編輯
同樣,我不能重寫fun.y,fun.z或fun.w, 只有ddply2. 因此,基于summarize()或count()將不起作用的解決方案無法推廣到其他功能。plyr:ddplyr不需要summarize()or count(),就是這樣。
uj5u.com熱心網友回復:
經過一番討論后,我現在明白,需要使用 dplyr 而不是 plyr 重寫此函式,這樣對于下面輸入部分中列出的輸入,它會給出相同的結果。
dd <- function(data, group, var, fun)
plyr::ddply(.data = data, .variables = group, var, .fun = fun)
為此,新函式可以將 group_by 與 summarise 或 group_modify 一起使用。下面的 dd1 使用第一個,dd2 使用第二個。使用任何你喜歡的。
請注意,fun.z 的撰寫方式假定一個資料幀而不是 tibble(因為如果只有一列,資料幀回傳一個向量,而 tibble 回傳另一個 tibble)所以我們使用 as.data.frame 來確保這一點。plyr 還回傳一個資料幀,在 dd1 和 dd2 結束時,我們將生成的 tibble 轉換為資料幀,以確保結果相同。
dd1 <- function(data, group, var, fun)
data %>%
group_by(across(all_of(group))) %>%
summarize(V1 = fun(as.data.frame(cur_data()), var), .groups = "drop") %>%
as.data.frame
dd2 <- function(data, group, var, fun)
data %>%
group_by(across(all_of(group))) %>%
group_modify(~ { data.frame(V1 = fun(as.data.frame(.), var)) }) %>%
ungroup %>%
as.data.frame
現在測驗一下
# inputs - start #
data <- mtcars
trim <- 0
na.rm <- FALSE
var <- "mpg"
group <- c("cyl", "am")
fun.z <- function(x, idx) {
as.numeric(mean(x[, idx], trim = trim, na.rm = na.rm))
}
# inputs - end #
library(dplyr)
dd.out <- dd(data, group, var, fun.z) # plyr
dd1.out <- dd1(data, group, var, fun.z)
dd2.out <- dd2(data, group, var, fun.z)
identical(dd1.out, dd.out)
## [1] TRUE
identical(dd2.out, dd.out)
## [1] TRUE
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/434866.html
