【发布时间】:2020-02-09 06:31:15
【问题描述】:
考虑一个 tibble,其中每一列都是一个字符向量,可以取多个值——比如说“A”到“F”。
library(tidyverse)
sample_df <- tibble(q1 = c("A", "B", "C"), q2 = c("B", "B", "A"))
我希望创建一个以列名作为参数的函数,并重新编码该列,以便任何答案“A”变为 NA,否则 df 按原样返回。以这种方式设计它的原因是为了适应更广泛的管道,该管道使用给定的列执行一系列操作。
有很多方法可以做到这一点。但我有兴趣了解最好的惯用 tidy_eval/tidyverse 方法是什么。首先,问题名称需要在变异动词的左侧,因此我们适当地使用!! 和:= 运算符。但是,在右手边放什么?
fix_question <- function(df, question) {
df %>% mutate(!!question := recode(... something goes here...))
}
fix_question(sample_df, "q1") # should produce a tibble whose first column is (NA, "B", "C")
我最初的想法是这会起作用:
df %>% mutate(!!question := recode(!!question, "A" = NA_character_))
当然,函数内部的 bang-bang 只返回文字字符串(例如“q1”)。我最终采用了一种感觉像是一条骇人听闻的路线来引用右侧的数据,使用基本的 R [[ 运算符并依赖 dplyr 的 . 构造,它有效,所以从某种意义上说我已经解决了我的根本问题:
df %>% mutate(!!question := recode(.[[question]], "A" = NA_character_))
我有兴趣从非常擅长 tidyeval 的人那里获得关于是否有更惯用的方法来执行此操作的反馈,希望看到一个有效的示例可以增强我对 tidyeval 函数集的更广泛理解。有什么想法吗?
【问题讨论】:
-
谢谢,这是一个聪明的方法——我确实在我的代码的其他部分使用了函数式方法,并且可以考虑在这里也这样做。我知道有些人对 SO 上的代码风格谈话不屑一顾,但这么快就看到几种不同风格的答案对我来说非常有成果。
-
结合这个问题的几个想法,我相信这是最简洁的版本,同时适用于
q1(符号)和"q1"(字符串):df %>% mutate_at( vars(!!ensym(question)), recode, A = NA_character_)
标签: r dplyr rlang tidyeval nse