Когда для фрейма данных вызывается with, как мы можем ссылаться на родительский фрейм данных, не используя его имя?

#r #environment

Вопрос:

Считать with(mtcars, split(mtcars,cyl == 8 amp; disp > 350)) . При написании сложного кода, особенно чего-либо более сложного, чем этот пример, with мы значительно сокращаем количество раз, которое нам нужно написать mtcars . Однако даже в этом простом примере мне пришлось писать mtcars дважды. Есть ли какой — нибудь способ обойти это при использовании with ? Может быть, что-то похожее на Recall() ? Что я хочу, так это как-то сказать with(data, foo(dataFrameThatMadeThisEnvironment(),partOfData)) .

Ответ №1:

В базе R. такой функции with нет. В основном это просто удобная оболочка для интерактивного использования. Вы могли бы довольно тривиально написать свой собственный

 withself <- function(data, expr) {
  env <- new.env(parent = parent.frame())
  env$self <- function() data
  eval(substitute(expr), data, enclos = env)
}
withself(mtcars, split(self(),cyl == 8 amp; disp > 350))
 

Из вас мог бы «взломать» стек with вызовов. Например

 withdata <- function() parent.frame(3)$data
with(mtcars, split(withdata(),cyl == 8 amp; disp > 350))
 

но на самом деле он не предназначен для такого использования.

В tidyverse мире вы избегаете повторения с помощью труб

 mtcars %>% 
  group_by(cyl == 8 amp; disp > 350) %>% 
  group_split()
 

Или просто с помощью оператора matrittr::%>% трубы

 mtcars %>% with(., split(., cyl == 8 amp; disp > 350))
 

Я не верю, что будущий собственный оператор R-труб позволит вам передавать одно и то же значение несколько раз, но я думаю, нам придется посмотреть, что будет делать окончательная версия.