R: нестандартная оценка с вложенными функциями - PullRequest
0 голосов
/ 02 марта 2019

У меня есть функция f1 на фрейме данных, которая вызывает другую функцию f2, а затем обрабатывает выходные данные f2.f2 работает в интерактивном режиме самостоятельно, но как мне заставить его работать при вызове f1?

f1 <- function(x, y) {
  z <- f2(x, y)

  # do stuff with z
  w <- z

  return(w)
}

f2 использует subset () для отмены выбора определенных столбцов:

f2 <- function(x, y) {
  y <- substitute(y)
  subset(x, select = -eval(y))
}

Как видите, f2 работает в интерактивном режиме.Меня это не волнует, но я хочу, чтобы оно работало при вызове f1.

# This works fine interactively (but I don't care about that)
f2(mtcars,mpg)

# This is what I want to work
f1(mtcars,mpg)
Error in -eval(y) : invalid argument to unary operator

Я бы предпочел не изменять f1 или его аргументы.Как мне переписать f2 так, чтобы он работал внутри f1?

Вот аналогичный вопрос с решениями, которые у меня возникают проблемы при применении к моему контексту: R: передача выражения во внутреннюю функцию

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

С более новой версией rlang 0.4.0 мы можем использовать {{...}} (вьюще-кудрявый), который облегчает оценку

library(rlang)
f1 <- function(x, y) {
  z <- f2(x, -{{y}})

  # do stuff with z
  w <- z

  return(w)
}

f2 <- function(x, y) {
  select(x, {{y}})
}


f1(mtcars,mpg) %>% 
      head
#                  cyl disp  hp drat    wt  qsec vs am gear carb
#Mazda RX4           6  160 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag       6  160 110 3.90 2.875 17.02  0  1    4    4
#Datsun 710          4  108  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive      6  258 110 3.08 3.215 19.44  1  0    3    1
#Hornet Sportabout   8  360 175 3.15 3.440 17.02  0  0    3    2
#Valiant             6  225 105 2.76 3.460 20.22  1  0    3    1
0 голосов
/ 02 марта 2019

Самым простым было бы использовать функции rlang и tidyverse для совместимости с квази-цитатой:

library(dplyr)
library(rlang)

f1 <- function(x, y) {
  z <- f2(x, -!!enquo(y))

  # do stuff with z
  w <- z

  return(w)
}

f2 <- function(x, y) {
  select(x, !!enquo(y))
}


f1(mtcars,mpg)
#                     cyl  disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4             6 160.0 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag         6 160.0 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710            4 108.0  93 3.85 2.320 18.61  1  1    4    1
# ...

Это работает в базе R:

f1 <- function(x, y) {
  z <- f2(x, substitute(y))

  # do stuff with z
  w <- z

  return(w)
}

f2 <- function(x, y) {
  eval(substitute(subset(x, select = -Y), list(Y = y)))
}

f1(mtcars,mpg)
#                     cyl  disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4             6 160.0 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag         6 160.0 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710            4 108.0  93 3.85 2.320 18.61  1  1    4    1
# ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...