动态dplyr列名计算

时间:2017-06-06 20:00:19

标签: r dynamic dplyr

我有以下代码。

传入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)
}

1 个答案:

答案 0 :(得分:5)

以下是如何使用新的tidyeval方法对dplyr 0.6.0进行非标准评估。 (我不确定它是否甚至可以用标准评估,至少以一种简单的方式):

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

enquo将未加引号的列名称转换为一个名为quosure的奇特对象。 !!然后取消引用quosure,以便可以对它进行评估,就好像它将直接在函数中输入一样。有关更深入和准确的解释,请参阅Hadley的"Programming with dplyr"

编辑:我意识到最初的问题是使用用户提供的值colName命名新列,而不只是colName,所以我更新了我的答案。要实现这一点,需要使用quo_name将quosure转换为字符串(或标签)。然后,它可以是&#34;未引用的&#34;使用!!就像常规的结果一样。唯一需要注意的是,由于R不能使表达式mutate(!!foo = bar)的头部或尾部,tidyeval引入新的定义运算符:=data.table的用户可能会熟悉它们。 1}}它有一些不同的用途)。与传统的赋值运算符=不同,:=运算符允许在右侧和左侧都取消引用。

(更新了使用其中一行NA的数据框的答案,以说明上一个mutate有效。我还使用count代替group by } + summarize,我放弃了不必要的rowwise。)