【问题标题】:Rename in dplyr 0.7+ function在 dplyr 0.7+ 函数中重命名
【发布时间】:2023-08-04 02:56:01
【问题描述】:

我在使用 dplyr 重命名函数中的列时遇到困难。我已经找到了关于非标准评估和 enquo 使用的有用帖子(例如,http://dplyr.tidyverse.org/articles/programming.htmlChanging names of resulting variables in custom dplyr function)。最终目标是使用该函数汇总每个组,然后将列重命名为比原始变量名称更有意义的名称。

这是一个简单的示例,除了注释掉的行之外,它都有效。

library(tidyverse)

myfunc <- function(df, groupvar, colvar, grouplab, collab) {
  groupvar <- enquo(groupvar)
  colvar <- enquo(colvar)
  grouplab <- enquo(grouplab)  # quo_name instead?
  collab <- enquo(collab)  # quo_name instead?

t <- df %>%
  select(!!groupvar, !!colvar) %>%
  group_by(!!groupvar, !!colvar) %>%
  summarise(
    Frequencies = length(!!colvar),
    Percentages = length(!!colvar) / nrow(df)
    ) %>%
  mutate(
    Frequencies = scales::comma(Frequencies),
    Percentages = scales::percent(Percentages)
    ) #%>%
# rename(
#    (!!grouplab) = !!groupvar,  # add a more descriptive grouping var label
#    (!!collab) = !!colvar)  # add a more descriptive column var label

# Error: unexpected '=' in: rename((!!grouplab) = "

...  # code to create an xtable, print it into LaTeX
}

myfunc <- (df = mtcars, groupvar = gear, colvar = cyl, grouplab = "Vehicle Gears", collab = "Vehicle Cylinders")
# I purposely made grouplab and collab have a space in case that changes anything. 

在函数之外,相关部分可以简单地写成:mtcars &lt;- mtcars %&gt;% rename("Vehicle Cylinders" = cyl, "Vehicle Gears" = gear)

我一定对重命名在函数内部和外部的操作方式感到困惑。有什么建议吗?我愿意接受建议。

更新
这是一种方法。我宁愿不把变量名放在字符串中,但不知道这里有什么办法。接受建议。

library(tidyverse)
library(xtable)
data(mtcars)

t_groupedfreqprop <- function(df, groupvar, colvar, grouplab, collab, plotname) {
groupvar2 <- rlang::sym(groupvar)
colvar2 <- rlang::sym(colvar)
grouplab <- rlang::sym(grouplab)
collab <- rlang::sym(collab)

t <- df %>%
  select(!!groupvar2, !!colvar2) %>%
  group_by(!!groupvar2, !!colvar2) %>%
  summarise(
    Frequencies = length(!!colvar2),
    Percentages = length(!!colvar2) / nrow(df)
  ) %>%
  mutate(
    Frequencies = scales::comma(Frequencies),
    Percentages = scales::percent(Percentages)
  ) %>%
  rename(
    !!grouplab := !!rlang::sym(groupvar2),
    !!collab := !!rlang::sym(colvar2)
  )

# remainder of function removed
}

t_groupedfreqprop(df = mtcars, groupvar = "gear", colvar = "cyl", grouplab = "Vehicle Gears", collab = "Vehicle Cylinders")

【问题讨论】:

    标签: r function dplyr nse rlang


    【解决方案1】:

    如果您希望在表达式的 LHS 上以编程方式分配名称,请使用 :=

    x <- "mpg"
    xnew <- "mpg2"
    rename(mtcars, !!xnew := !!rlang::sym(x))
    

    【讨论】:

    • 谢谢@Hong Ooi。这种技术是否仍然适用于函数 - 即,我没有对新名称进行硬编码?
    • 是的,它应该可以工作,但你必须使用enquo 引用xxnew 然后你可以取消引用。有关 tidyeval 概念的更多信息,请参阅 dplyr 中的编程小插图。
    • 谢谢。我一定还是遗漏了一些东西......将函数归结为相关部分会引发错误:“错误:只有字符串可以转换为符号。”这个小插曲有帮助(cran.r-project.org/web/packages/rlang/vignettes/…),但我仍然在为如何在函数内部工作而苦苦挣扎。 t_groupedfreqprop % rename( !!grouplab := !!rlang::sym(groupvar)) } t_groupedfreqprop(df = mtcars, groupvar = gear, grouplab = "Vehicle Gears")
    【解决方案2】:

    要一次重命名多个列,您必须使用!!!

    x <- c("mpg", "cyl")
    xnew <- paste(x, 2, sep = ".")
    names(x) <- xnew
    rename(mtcars, !!!x)
    

    【讨论】: