使用Rlang:在一组定律中查找数据代词

安德鲁·希尔

我有一组quasure,用于使用dplyr生成摘要统计信息集。

我想知道正在使用哪些数据列。

数据列的前缀为.data [[“ ColumnName”]]。

因此,例如,我们有:

my_quos <- rlang::list2(
  "GenderD" = rlang::quo(length(.data[["TeamCode"]])),
  "GenderMaleN" = rlang::quo(.data[["S1IsMale"]])
)

我已经开始通过使用rlang :: call_args()将命令分解成其组件来解决此问题:

my_args_test <- rlang::call_args(my_quos[[1]])
str(my_args_test)
List of 1
 $ : language .data[["TeamCode"]]

这些列都应该作为数据代词。有没有一种快速的方法来检查列表中的项目是否为数据代词?我试过了:

is(my_args_test[[1]], "rlang_data_pronoun")

但这返回false。我猜将字符串检查为以.data [[开头的文本]是一个选项(但我怀疑这更容易出错)。

还有一种方法可以干净地返回传递给数据代词的参数,而不是解析字符串吗?换句话说,目标是理想地将我们的输出返回为:

c("TeamCode", "S1IsMale")

来自原始的my_quos。

阿尔特姆·索科洛夫(Artem Sokolov)

这可以分两个步骤完成。首先,您要提取您的quasure捕获的表达式并将它们转换为Abstract Syntax Trees(ASTs)

## Recursively constructs Abstract Syntax Tree for a given expression
getAST <- function( ee ) { as.list(ee) %>% purrr::map_if(is.call, getAST) }

## Apply function to expressions captured by each quosure
asts <- purrr::map( my_quos, quo_get_expr ) %>% purrr::map( getAST )
str(asts)
# List of 2
#  $ GenderD    :List of 2
#   ..$ : symbol length
#   ..$ :List of 3
#   .. ..$ : symbol [[
#   .. ..$ : symbol .data
#   .. ..$ : chr "TeamCode"
#  $ GenderMaleN:List of 3
#   ..$ : symbol [[
#   ..$ : symbol .data
#   ..$ : chr "S1IsMale"

从这里,我们看到模式匹配.data[["somename"]]是一个length-3列表,其中第一个条目是[[,第二个条目是.data,最后一个条目是您要提取的内容。让我们编写一个识别此模式并在识别后返回第三个元素的函数(注意:此函数显示如何将.data代词代词匹配,这是您的另一个问题)

## If the input matches .data[["name"]], returns "name". Otherwise, NULL
getName <- function( x )
{
  if( is.list(x) && length(x) == 3 &&          ## It's a length-3 list
      identical( x[[1]], quote(`[[`) ) &&      ##  with [[ as the first element
      identical( x[[2]], quote(.data) ) &&     ##  .data as the second element
      is.character(x[[3]]) ) return(x[[3]])    ##  and a character string as 3rd
  NULL
}

有了此功能,第二步就是简单地将其递归应用于AST列表,以提取使用的列名。

getNames <- function( aa ) { 
  purrr::keep(aa, is.list) %>% 
  purrr::map(getNames) %>%            ## Recurse to any list descendants
  c( getName(aa) ) %>%                ## Append self to the result
  unlist                              ## Return as character vector, not list
}

getNames(asts)
#     GenderD GenderMaleN 
#  "TeamCode"  "S1IsMale" 

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章