Использование пакета rlang для разбора цитируемого аргумента - PullRequest
0 голосов
/ 13 ноября 2018

Я надеюсь разделить строку одного аргумента на два аргумента и использовать каждый в разных разделах функции.

Возможно ли это сделать с помощью квазиквотации (!!) или других функций rlang?

Спасибо!

Данные:

person <- tibble(id = 1, age = 20)
friends <- tibble(id = c(2, 3, 4, 5), age = c(48, 29, 20, 48))

(не функционирует) Функция:

different_age_friends <- function(condition, person = person, friends = friends ) {

  person <- person
  friends <- friends

  condition <- str_split(condition, " ~ ", simplify = T)
  condition_statement <- condition[1]
  filter_statement <- condition[2]

  if(!!condition_statement) {
    different_age_friends <- friends %>%
      filter(!!filter_statement)
  }

  return(return_same_age_friends)
}

Звоните:

different_age_friends(condition = "age == 20 ~ age == 48")

Желаемый выход

id age
2  48
5  48

1 Ответ

0 голосов
/ 13 ноября 2018

Используйте rlang::parse_expr для преобразования строк в выражения и eval для их оценки.eval() позволяет вам предоставить контекст для выражения во втором аргументе, где мы предоставляем ему фрейм данных person.В случае filter контекст уже понимается как фрейм данных в левой части канала %>%.

Другое отличие в том, как мы обрабатываем два выражения, заключается в том, что filter() имеетдополнительный внутренний слой квазикватация .Поскольку у вас уже есть выражение, вам не нужно его снова заключать в кавычки, поэтому вы должны использовать !! для его удаления.

different_age_friends <- function(condition, p = person, f = friends) 
{
  stmts <- str_split(condition, " ~ ")[[1]] %>% map( rlang::parse_expr )

  if( eval(stmts[[1]], p) )         # Effectively: eval(age == 20, person)
    f %>% filter(!!stmts[[2]])      # Effectively: friends %>% filter(age == 48)
  else
    f
}

different_age_friends(condition = "age == 20 ~ age == 48")
# # A tibble: 2 x 2
#      id   age
#   <dbl> <dbl>
# 1     2    48
# 2     5    48

Небольшое примечание:

  • Вы не указали значение для different_age_friends, когда условие ложно.Я сделал предположение, что в этом случае должен быть возвращен весь список друзей.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...