我有以下代码.
传入colName.我一直试图将它作为colName的值进行评估,但没有取得多大成功.我试过"eval","setNames"等.使用"_",仍然没有提供成功.
基本上,如果我的colName ="MyCol",我希望dplyr链执行,如同最后一行读取:
mutate(MyCol = ifelse(is.na(MyCol), "BLANK", MyCol))
makeSummaryTable <- function(colName,originalData){
result <- originalData %>%
group_by_(colName) %>%
summarise(numObs = n()) %>%
ungroup() %>%
arrange(desc(numObs)) %>%
rowwise() %>%
mutate_(colName = ifelse(is.na(colName), "BLANK",colName))
return(result)
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用dplyr 0.6.0使用新tidyeval方法进行非标准评估.(我不确定是否可以使用标准评估,至少以简单的方式):
library(dplyr)
makeSummaryTable <- function(colName, originalData){
colName <- enquo(colName)
originalData %>%
count(!!colName) %>%
arrange(desc(n)) %>%
mutate(
old_col = !!colName,
!!quo_name(colName) := if_else(is.na(!!colName), "BLANK",!!colName)
)
}
makeSummaryTable(hair_color, starwars)
#> # A tibble: 13 x 3
#> hair_color n old_col
#> <chr> <int> <chr>
#> 1 none 37 none
#> 2 brown 18 brown
#> 3 black 13 black
#> 4 BLANK 5 <NA>
#> 5 white 4 white
#> 6 blond 3 blond
#> 7 auburn 1 auburn
#> 8 auburn, grey 1 auburn, grey
#> 9 auburn, white 1 auburn, white
#> 10 blonde 1 blonde
#> 11 brown, grey 1 brown, grey
#> 12 grey 1 grey
#> 13 unknown 1 unknown
Run Code Online (Sandbox Code Playgroud)
enquo将不带引号的列名称转换为一个名为quosure的奇特对象.!!然后取消引用quosure,以便它可以被评估,就好像它将直接在函数中输入一样.有关更深入和准确的解释,请参阅Hadley的"使用dplyr编程".
编辑:我意识到原来的问题是用用户提供的值命名新列,colName而不仅仅是colName我更新了我的答案.要实现这一点,需要将quosure转换为字符串(或标签)quo_name.然后,它可以被"不加引号"使用,!!就像常规的quosure一样.唯一要注意的是,由于R不能使头部或表达的尾部mutate(!!foo = bar),tidyeval引入了新的定义操作者:=(其可能是从为用户所熟悉data.table,其中它有一个稍微不同的使用).与传统的赋值运算符不同=,:=运算符允许在右侧和左侧进行取消引用.
(更新了使用NA其中一行中的数据框的答案,以说明最后一行mutate.我也使用了count代替group by+ summarize,我删除了不必要的rowwise.)