【问题标题】:Write a function with default column name inputs in dplyr::mutate()在 dplyr::mutate() 中编写一个具有默认列名输入的函数
【发布时间】:2019-05-15 00:16:48
【问题描述】:

我正在尝试编写一个函数来计算数据框中的新列。我希望该函数具有默认列名作为输入,并且能够从 dplyr::mutate() 中调用。

这是一个简化的示例,我使用名为 age 的列来计算四舍五入的年龄。

library(dplyr)
# function to round age WITH DEFAULT vector/column to round
round_age <- function(age = age) {
  round(age)
}

# create dummy data
data = data.frame(age = c(50.1, 60.5))

# try to use default age column - ERROR
data %>%
  mutate(
    age_round = round_age()
  )
#> Error in mutate_impl(.data, dots): Evaluation error: non-numeric argument to mathematical function.

# specify age column to round - NO ERROR
data %>%
  mutate(
    age_round = round_age(age = age)
  )
#>    age pat_age age_round
#> 1 50.1    50.1        50
#> 2 60.5    60.5        60

我希望能够在不指定数据框的情况下从dplyr::mutate 中调用该函数。有任何想法吗?非常感谢所有提示!

谢谢! 丹尼尔

【问题讨论】:

  • data$age?!也许?!
  • 您的问题涉及标准评估。请参阅dplyr.tidyverse.org/articles/programming.html 以获得一些帮助。同时,我将查看一些我绕过这个问题的旧代码。到时候别人也可以回答。
  • @hmhensen 我认为你是对的。我无法将 bang-bang、enquo()rlang 语法转换为不包含数据框作为函数输入的东西。

标签: r dplyr tidyverse


【解决方案1】:

我们可以编写一个名为round_x() 的函数,它环绕mutate() 并以age 作为默认参数:

library(dplyr)

round_x <- function(.data, x = age) {
  x <- enquo(x)
  var_name <- paste0("round_", quo_name(x))
  mutate(.data, !!var_name := round(!!x))
}

如果我们不带参数调用这个函数:

data %>% round_x()
#   age round_age
#1 50.1        50
#2 60.5        60

如果我们愿意,我们可以传递其他参数:

data.frame(data, weight = c(180.5, 200.6)) %>% round_x(weight)
#   age weight round_weight
#1 50.1  180.5          180
#2 60.5  200.6          201

【讨论】:

  • 我总是与quoenquo 和一般报价作斗争。你介意解释一下quo_name!!var_name!!x 在做什么吗?谢谢
  • quo_name 仅返回包含在 quosure 中的表达式的字符串(在round_x() 中,它始终只是您传递给x 的字符串,因此它将默认为@ 987654337@)。 !!var_name 取消引用 var_name,其中包含一个字符串 "round_age",并使用特殊的 := 运算符将其分配给我们的新变量的名称。 !!x 取消引用x,这是我们用x &lt;- enquo(x) 创建的一个quosure,其中包含一个表达式~age——取消引用告诉我们在@987654346 指定的数据框的上下文中查找变量age @代词。
  • 我还建议阅读 dplyr vignette (cran.r-project.org/web/packages/dplyr/vignettes/…) 的编程以获得更好的解释,或者如果你想要一个非常熟悉的 WIP 版本 Advanced R (adv-r.hadley.nz/meta.html) 中的元编程章节深度解释。我仍在努力解决所有这些问题。
  • 感谢@DiceboyT,将数据帧传递给函数的解决方案效果很好。但是,我正在尝试从mutate() 中获得解决方案。我目前正在教我的团队 R,并且我正在尝试使所有语法尽可能相似(即,使用 mutate() 在数据框中创建新列)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多