【问题标题】:How can I use Quasiquotation in the context of tidyeval in tidyverse scoped verbs or a mapper?如何在 tidyverse 范围动词或映射器的 tidyeval 上下文中使用 Quasiquotation?
【发布时间】:2019-02-08 12:27:28
【问题描述】:

我在映射器函数中使用特殊运算符:=(冒号等于)时遇到问题。我找到了使用 tidyverse 中的作用域动词的解决方法,但我想知道特殊运算符在映射器函数中的实现方式。

基本上,我想分别用关联的属性标签重命名一组变量。我编写了用于重命名单个变量的函数,但我不知道如何使用作用域动词变体或映射器以相同的样式编写它。

这是我的可重现示例:

我可以这样做重命名一个变量:

library(tidyverse)
library(sjlabelled)
library(rlang) 

data(efc)

dat <- efc %>%
  rename(!!paste("c12hour", get_label(., c12hour), sep = "_") := c12hour)

# c12_hour becomes this:
names(dat[1])
[1] "c12hour_average number of hours of care per week"

我想将此函数应用于作用域动词rename_all,我认为它看起来像这样,但会导致错误:

dat <- efc %>%
  rename_all(~!!paste(., get_label(.), sep = "_") := .)
Error: `:=` can only be used within a quasiquoted argument

当我尝试使用映射器时也会出现此错误:

geo_rename <- as_mapper(~rename(!!paste(., get_label(.), sep = "_") := .))

dat <- efc %>%
  map_dbl(., geo_rename)
Error: `:=` can only be used within a quasiquoted argument
Call `rlang::last_error()` to see a backtrace

我猜问题在于:= 运算符的使用,它是为tidyeval 框架中出现的准引用问题而发明的。我在函数式编程的上下文中使用错了吗?

我找到了一种解决方法,方法是将要粘贴到的标签保存在命名列表中:

dat <- efc

dat_labels <- get_label(dat)
dat_recode <- as.list(as.character(dat_labels))
names(dat_recode) <- get_label(dat)

dat <- efc %>%
  select_all(~paste(., dat_recode, sep = "_"))

但我想知道如何在函数式编程中使用:=。在 Hadley Wickham 的书中,它被简短地介绍过,但没有用于作用域动词或映射器函数https://adv-r.hadley.nz/quasiquotation.html#tidy-dots

谁能给我解释一下?

提前致谢!

【问题讨论】:

    标签: r tidyeval


    【解决方案1】:

    rename_all() 等作用域变体不使用 tidy eval。他们就像 purrr 中的映射器,或者lapply()

    mtcars %>% rename_all(toupper)
    

    或者使用 lambda 函数的公式表示法:

    mtcars %>% rename_all(~ toupper(.x))
    

    此外,对于rename_all(),映射函数的输入是列name,而不是具有标签属性的列向量。

    所以恐怕您需要找到不同的解决方案。 tidy eval 和 scoped 变体都超出了这个问题的解决方案空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-11
      • 2014-08-03
      • 1970-01-01
      • 2023-01-09
      • 2020-03-09
      • 2018-07-17
      • 1970-01-01
      相关资源
      最近更新 更多