我想使用 dplyr 包中的 group_by
和 group_map
而不是 split
和 map
。然而,我遇到了一个相当奇怪的问题。
我就是这么做的
library(dplyr)
df = tibble(
name = rep(c("a", "b", "c"), 100),
x = rep(1:100, each=3),
y = rnorm(300)
)
f1 = function(df, par1 = FALSE, par2 = FALSE){
paste(par1, par2, df$name[1], mean(df$y))
}
现在,如果我运行这样的命令,一切看起来都很好
df %>%
split(.$name) %>%
map(f1)
$a
[1] "FALSE FALSE a -0.111419050033957"
$b
[1] "FALSE FALSE b -0.0715780638158137"
$c
[1] "FALSE FALSE c 0.13736619417831"
如果我设置了可选参数,一切都很好
df %>%
split(.$name) %>%
map(f1, par1 = TRUE, par2 = TRUE)
$a
[1] "TRUE TRUE a -0.111419050033957"
$b
[1] "TRUE TRUE b -0.0715780638158137"
$c
[1] "TRUE TRUE c 0.13736619417831"
当我尝试使用 group_by
和 group_map
获得相同的效果时,出现了错误
df %>%
group_by(name) %>%
group_map(f1, .keep = TRUE)
[[1]]
[1] "a FALSE a -0.111419050033957"
[[2]]
[1] "b FALSE b -0.0715780638158137"
[[3]]
[1] "c FALSE c 0.13736619417831"
如您所见,可选参数 par1
接收的值是数据组的名称。这不是我所期望的!
如果我设置 par1
,则 par2
获取这些值。
df %>%
group_by(name) %>%
group_map(f1, par1 = TRUE, .keep = TRUE)
[[1]]
[1] "TRUE a a -0.111419050033957"
[[2]]
[1] "TRUE b b -0.0715780638158137"
[[3]]
[1] "TRUE c c 0.13736619417831"
但是当我尝试设置两个可选参数时,出现错误!
df %>%
group_by(name) %>%
group_map(f1, par1 = TRUE, par2 = TRUE, .keep = TRUE)
Error in (function (df, par1 = FALSE, par2 = FALSE) :
unused argument (dots[[2]][[1]])
我必须承认,我对函数 group_map
的这种行为感到惊讶。
这真的是它应该工作的方式吗,还是我做错了什么,或者我对某些事情理解不好。
最佳答案
您可以在 dplyr::group_map
的 .f
参数中使用函数名称。但是您必须记住 .f
中的函数必须至少接受两个参数: .x
第一个参数是 data.frame
和 .y
包含分组变量的 tibble
。
文档在详细信息部分说了这一点:
Each conceptual group of the data frame is exposed to the function .f with two pieces of information:
The subset of the data for the group, exposed as .x.
The key, a tibble with exactly one row and columns for each grouping variable, exposed as .y.
.x
和 .y
将始终是 .f
中函数的前两个参数,这会导致您的问题,因为我们从错误信息中可以看到:
df %>%
group_by(name) %>%
group_map(.f = f1,
par1 = TRUE,
par2 = TRUE,
.keep = TRUE)
#> Error in (function (df, par1 = FALSE, par2 = FALSE) : unused argument (dots[[2]][[1]])
此处 .y
被传递给您的函数 f1
,该函数没有与之匹配的参数。
让我们重写函数 f1
,以便它采用 .y
(组名称 (grp_nm
))作为第二个参数。我们将使用这个参数来打印出来看看 .y
是什么:
library(dplyr)
df = tibble(
name = rep(c("a", "b", "c"), 100),
x = rep(1:100, each=3),
y = rnorm(300)
)
f1 = function(df, grp_nm, par1 = FALSE, par2 = FALSE){
print(grp_nm)
paste(par1, par2, df$name[1], mean(df$y))
}
df %>%
group_by(name) %>%
group_map(.f = f1,
par1 = TRUE,
par2 = TRUE,
.keep = TRUE)
#> # A tibble: 1 x 1
#> name
#> <chr>
#> 1 a
#> # A tibble: 1 x 1
#> name
#> <chr>
#> 1 b
#> # A tibble: 1 x 1
#> name
#> <chr>
#> 1 c
#> [[1]]
#> [1] "TRUE TRUE a -0.0371737353510479"
#>
#> [[2]]
#> [1] "TRUE TRUE b -0.00874656816210368"
#>
#> [[3]]
#> [1] "TRUE TRUE c -0.030588993215492"
由 reprex package 于 2021 年 8 月 25 日创建(v2.0.1)
当然,我们不需要 grp_nm
参数,因此最简单的方法是将省略号 ...
添加到您的函数中,这将防止出现上面的错误:
f1 = function(df, ..., par1 = FALSE, par2 = FALSE){
paste(par1, par2, df$name[1], mean(df$y))
}
因此这里没有要报告的错误 dplyr::group_map
正在按预期工作。
关于r - 可能是 group_map 命令有问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68928553/