R dplyr对仅由其字符串名称知道的列进行操作

bmo*_*v01 1 r dynamic quoting dplyr rlang

我正在努力使用dplyrR中的编程来操作数据帧的列,这些列只能通过它们的字符串名称来识别.我知道最近有一个dplyr支持quouts等的更新,我在这里回顾了我认为新的"用dplyr编程"一文的相关组成部分:http://dplyr.tidyverse.org/articles/programming .html.但是,我仍然无法做我想做的事.

我的情况是我只知道数据框的字符串名称.因此,我无法dplyr在函数内调用甚至是在运行之间列名可能会更改的脚本中使用非标准求值,因为我不能硬编码未加引号(即"裸")列名称.我想知道如何解决这个问题,我猜我用新的引用/取消引用语法忽略了一些东西.

例如,假设我有用户输入来定义数据分布的截止百分位数.用户可以使用他/她想要的任何百分位来运行代码,并且他/她选择的百分位将改变输出.在分析中,使用所使用的百分位名称创建中间数据框中的列; 因此,该列的名称根据用户输入的截止百分位数而变化.

下面是一个最小的例子来说明.我想用截止百分位数的各种值来调用函数.我希望命名的数据框MPGCutoffs有一个根据所选截止分位数命名的列(这当前在下面的代码中有效),我想稍后对这个列名进行操作.由于这个列名的一般性,我只能在pctCutoff编写函数时根据输入知道它,所以我需要一种方法来操作它,只知道定义的字符串probColName,它遵循基于预定义的模式关于价值pctCutoff.

userInput_prob1 <- 0.95
userInput_prob2 <- 0.9

# Function to get cars that have the "best" MPG
# fuel economy, where "best" is defined by the
# percentile cutoff passed to the function.
getBestMPG <- function( pctCutoff ){

  # Define new column name to hold the MPG percentile cutoff.
  probColName <- paste0('P', pctCutoff*100)

  # Compute the MPG percentile cutoff by number of gears.
  MPGCutoffs <- mtcars %>%
    dplyr::group_by( gear ) %>%
    dplyr::summarize( !!probColName := quantile(mpg, pctCutoff) )

  # Filter mtcars with only MPG values above cutoffs.
  output <- mtcars %>%
    dplyr::left_join( MPGCutoffs, by='gear' ) %>%
    dplyr::filter( mpg > !!probColName ) #****This doesn't run; this is where I'm stuck

  # Return filtered data.
  return(output)
}

best_1 <- getBestMPG( userInput_prob1 )
best_2 <- getBestMPG( userInput_prob2 )
Run Code Online (Sandbox Code Playgroud)

dplyr::filter()声明是什么,我不能得到正常运行.我试过了:

dplyr::filter( mpg > probColName ) - 没有错误,但没有返回任何行.

dplyr::filter( mpg > !!probColName ) - 没有错误,但没有返回任何行.

我也看过一些例子,我可以把它传递quo(P95)给函数,然后在调用中取消引用它dplyr::filter(); 我已经得到了这个,但它并没有解决我的问题,因为它需要在函数外部对变量名进行硬编码.例如,如果我执行此操作并且用户传递的百分位数为0.90,则调用将dplyr::filter()失败,因为创建的列是命名的P90而不是P95.

任何帮助将不胜感激.我希望有一个简单的解决方案,我只是忽略了.

MrF*_*ick 8

如果你在一个字符串(也就是字符向量)中有一个列名,并且你想将它与tidyeval一起使用,那么你可以用它来转换它rlang::sym().只是改变

dplyr::filter( mpg > !!rlang::sym(probColName) )
Run Code Online (Sandbox Code Playgroud)

它应该工作.这取自此github问题的建议:https://github.com/tidyverse/rlang/issues/116

它仍然可以使用

dplyr::summarize( !!probColName := quantile(mpg, pctCutoff) )
Run Code Online (Sandbox Code Playgroud)

因为在动态设置参数名称时,您只需要字符串而不是未标记的符号.