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

R dplyr对只知道其字符串名的列进行操作,r,dynamic,dplyr,quoting,rlang,R,Dynamic,Dplyr,Quoting,Rlang,我正在努力使用R中的dplyr对数据帧中只有字符串名才能知道的列进行操作。我知道最近更新了dplyr以支持quosures等,我在这里回顾了我认为新的“使用dplyr编程”文章的相关组件:。然而,我仍然不能做我想做的事 我的情况是,我只知道数据帧的字符串名。因此,我不能在函数中调用dplyr,甚至在脚本中使用非标准求值,因为在运行期间列名可能会发生变化,因为我通常不能硬编码不带引号(即“裸”)的列名。我想知道如何解决这个问题,我猜我忽略了新的引用/取消引用语法 例如,假设我有定义数据分布的截止百

我正在努力使用R中的
dplyr
对数据帧中只有字符串名才能知道的列进行操作。我知道最近更新了
dplyr
以支持quosures等,我在这里回顾了我认为新的“使用dplyr编程”文章的相关组件:。然而,我仍然不能做我想做的事

我的情况是,我只知道数据帧的字符串名。因此,我不能在函数中调用
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 )

userInput\u prob1如果您在字符串(也称为字符向量)中有一个列名,并且希望将其与tidyeval一起使用,则可以使用
rlang::sym()
对其进行转换。换衣服

dplyr::filter( mpg > !!rlang::sym(probColName) )
它应该会起作用。这摘自本期github的建议:

它仍然可以使用

dplyr::summarize( !!probColName := quantile(mpg, pctCutoff) )

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

以下是哈德利在帖子中的评论的另一种解决方案,该评论在Flick先生的回答()中提到。使用base R中的
as.name()
代替
rlang::sym()
,您仍然需要将其取消引用。也就是说,以下各项也起作用:


dplyr::filter(mpg>!!as.name(probColName))

这正是我想要做的,谢谢@MrFlick。问题:当我计算
str(rlang::sym(probColName))
时,它返回
symbol 95
(或根据
pctCutoff
的值的其他数字。
!!
运算符在符号的情况下做什么?它是否将其转换为一个无引号的变量名?符号就像没有环境的quosure。基本上!!测试符号和quosure相同。符号是一个无引号的变量名。即tidyeval之前使用的hat one改变了范式。我感兴趣的是,如果符号只是一个简单的无引号变量名,那么符号上仍然需要unquote运算符
!!
,这是
dplyr
动词使用NSE所期望的。无论如何,这解决了我已经有一段时间的问题,并且更新了quosure处理使用最新版本的
dplyr
,将能够对使用
dplyr
动词的函数的泛型参数进行更为精简的处理。感谢您的深入了解!它确实与何时需要计算符号以及何时需要取消计算符号有更多关系。使用!!可以更好地控制这些参数。如果您检查
?sym
帮助页,您可以看到它们处理编码的方式不同,但在其他方面基本相同。