Использование Rlang: найти местоимение данных в наборе фраз - PullRequest
0 голосов
/ 28 мая 2018

У меня есть набор предложений, которые используются для создания наборов сводной статистики с использованием dplyr.

Я хочу знать, какие столбцы данных используются.

Столбцы данных имеют префиксby .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")

Но это возвращает ложь.Проверка строки как текста, начинающегося с .data [[может быть, вариант, я думаю (но я подозреваю, что это более подвержено ошибкам).

Также есть способ аккуратно вернуть параметр, переданный в местоимение данных, а неРазбор строки?Другими словами, цель состоит в том, чтобы в идеале вернуть наш результат:

c("TeamCode", "S1IsMale")

Из исходного my_quos.

1 Ответ

0 голосов
/ 21 августа 2018

Это можно сделать в два этапа.Сначала вы хотите извлечь выражения, захваченные вашими предложениями, и преобразовать их в Абстрактные деревья синтаксиса (AST) .

## 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"]], имеет видсписок длины 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" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...