Как запрограммировать выражение операции set в качестве аргумента функции? - PullRequest
0 голосов
/ 26 февраля 2019

Если у меня есть функция f:


f <- function(a = character(0),
              b = character(0),
              c = character(0),
              condition = "a + b + c") {

  if(condition == "a + b + c")
    return(union(union(a, b), c))

  if(condition == "(a * b) + c")
    return(union(intersect(a, b), c))

  if(condition == "(a - b) + c")
    return(union(setdiff(a, b), c))

  if(condition == "(a - b) - c")
    return(setdiff(setdiff(a, b), c))

  # etc...

}


f(a = c('1', '2', '3'),
  b = c('2', '3', '4'),
  c = c('3', '4'),
  condition = "a + b + c")
#> [1] "1" "2" "3" "4"

f(a = c('1', '2'),
  b = c('2', '3'),
  c = c('2', '3', '4'),
  condition = "(a * b) + c")
#> [1] "2" "3" "4"

f(a = c('1', '2'),
  b = c('2', '3'),
  c = c('2', '3', '4'),
  condition = "(a - b) - c")
#> [1] "1"

Как решить проблему кодирования этого аргумента condition, который должен определять выражение операции набора для входных векторов?

В моем примере я использовал простые строки только для иллюстрации предполагаемого поведения, однако это решение не хорошо масштабируется.Нужно ли использовать языковой объект (?!) ...

Мне нужен простой способ:

  1. , указав это выражение (строка может быть хорошим объектом?);
  2. как-то проанализировать его и убедиться, что оно преобразуется в допустимое выражение операции набора;
  3. Вычислить результат, применив вышеупомянутое выражение операции набора.

1 Ответ

0 голосов
/ 26 февраля 2019

Одна вещь, которую вы могли бы сделать, это просто проанализировать выражение, а затем заменить +, - и * соответствующими функциями.Тогда вы можете просто оценить это выражение.Например,

f <- function(a = character(0),
              b = character(0),
              c = character(0),
              condition = "a + b + c") {

  parsed_cond <- parse(text=condition)[[1]]
  translated_expr <- do.call("substitute", list(
      parsed_cond,
      list(`+`=quote(union),
           `-`=quote(setdiff),
           `*`=quote(intersect))
   ))
   eval(translated_expr)
}

Возвращает значения, которые вы даете в своем примере

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