当我在
group_by(col)
内使用 lapply()
时,列 a
和 b
被重命名为 get(col)
。我该如何阻止这种情况发生?我想在新对象中保留原始列名称。
MRE
输入
df <- data.frame(a = c(1, 1, 1), b = c(1, 1, 1), c = c(1, 1, 1))
lapply(c("a", "b"), function(col) {
assign(col, df %>% group_by(get(col)) %>% summarize(), env = .GlobalEnv)
})
输出
[[1]]
# A tibble: 1 × 1
`get(col)`
<dbl>
1 1
[[2]]
# A tibble: 1 × 1
`get(col)`
<dbl>
1 1
如果有人解释“为什么”会发生这种重命名,以及如何阻止它,那就太好了。预先感谢。
group_by_at
代替:
lapply(c("a", "b"), function(col) {
assign(col, df %>% group_by_at(col) %>% summarize(), env = .GlobalEnv)
})
[[1]]
# A tibble: 1 × 1
a
<dbl>
1 1
[[2]]
# A tibble: 1 × 1
b
<dbl>
1 1
get
中使用
group_by
。这与非标准评估效果不佳。不过有几种选择。你可以使用!!ensym(col)
:
lapply(c("a", "b"), function(col) {
assign(col, df %>% group_by(!!ensym(col)) %>% summarize(), env = .GlobalEnv)
})
类似的方法是
!!str2lang(col)
lapply(c("a", "b"), function(col) {
assign(col, df %>% group_by(!!str2lang(col)) %>% summarize(), env = .GlobalEnv)
})
不过,推荐的方法似乎是使用
pick(all_of(col))
lapply(c("a", "b"), function(col) {
assign(col, df %>% group_by(pick(all_of(col))) %>% summarize(),
env = .GlobalEnv)
})
或
across(all_of(col))
:
lapply(c("a", "b"), function(col) {
assign(col, df %>% group_by(across(all_of(col))) %>% summarize(),
env = .GlobalEnv)
})
group_by_at
函数非常适合这种情况,但已被取代并且可能很快就会被弃用。无论如何,所有这些都会导致:
a
#> # A tibble: 1 x 1
#> a
#> <dbl>
#> 1 1
b
#> # A tibble: 1 x 1
#> b
#> <dbl>
#> 1 1
请注意,以这种方式将
assign
变量添加到全局工作区被认为是不好的做法。将结果保存在列表中几乎总是更好:
dfs <- lapply(c("a", "b"), function(col) {
df %>% group_by(across(all_of(col))) %>% summarize()
}) |>
setNames(c("a", "b"))
dfs
#> $a
#> # A tibble: 1 x 1
#> a
#> <dbl>
#> 1 1
#>
#> $b
#> # A tibble: 1 x 1
#> b
#> <dbl>
#> 1 1
创建于 2023-09-14,使用