阻止 tidyverse 在 lapply 中重命名列

-1 r lapply dplyr data-cleaning tidyverse

当我使用group_by(col)inside时lapply(),columnsab被重命名为get(col). 我该如何阻止这种情况发生?我想在新对象中保留原始列名。

\n

磁力RE

\n

输入

\n
df <- data.frame(a = c(1, 1, 1), b = c(1, 1, 1), c = c(1, 1, 1))\n\nlapply(c("a", "b"), function(col) {\n  \n  assign(col, df %>% group_by(get(col)) %>% summarize(), env = .GlobalEnv)\n  \n})\n
Run Code Online (Sandbox Code Playgroud)\n

输出

\n
[[1]]\n# A tibble: 1 \xc3\x97 1\n  `get(col)`\n       <dbl>\n1          1\n\n[[2]]\n# A tibble: 1 \xc3\x97 1\n  `get(col)`\n       <dbl>\n1          1\n
Run Code Online (Sandbox Code Playgroud)\n

如果有人解释原因那就太好了会发生这种重命名以及如何阻止它,提前致谢。

\n

All*_*ron 5

你不能get在里面使用group_by。这与非标准评估效果不佳。但有几种选择。

你可以使用!!ensym(col)

lapply(c("a", "b"), function(col) {
  assign(col, df %>% group_by(!!ensym(col)) %>% summarize(), env = .GlobalEnv)
})
Run Code Online (Sandbox Code Playgroud)

类似的方法是!!str2lang(col)

lapply(c("a", "b"), function(col) {
  assign(col, df %>% group_by(!!str2lang(col)) %>% summarize(), env = .GlobalEnv)
})
Run Code Online (Sandbox Code Playgroud)

然而,推荐的方法似乎是使用pick(all_of(col))

lapply(c("a", "b"), function(col) {
  assign(col, df %>% group_by(!!str2lang(col)) %>% summarize(), env = .GlobalEnv)
})
Run Code Online (Sandbox Code Playgroud)

或者across(all_of(col))

lapply(c("a", "b"), function(col) {
  assign(col, df %>% group_by(pick(all_of(col))) %>% summarize(), 
         env = .GlobalEnv)
})
Run Code Online (Sandbox Code Playgroud)

group_by_at函数非常适合这种情况,但已被取代并且可能很快就会被弃用。无论如何,所有这些都会导致:

lapply(c("a", "b"), function(col) {
  assign(col, df %>% group_by(across(all_of(col))) %>% summarize(), 
         env = .GlobalEnv)
})
Run Code Online (Sandbox Code Playgroud)

assign请注意,以这种方式将变量添加到全局工作区被认为是不好的做法。将结果保存在列表中几乎总是更好:

a
#> # A tibble: 1 x 1
#>       a
#>   <dbl>
#> 1     1

b
#> # A tibble: 1 x 1
#>       b
#>   <dbl>
#> 1     1
Run Code Online (Sandbox Code Playgroud)

创建于 2023-09-14,使用reprex v2.0.2

  • 不要忘记`.data[[col]]`,它可能应该比您在本例中给出的其他方法更值得推荐。 (3认同)