Точка, сохраненная в вызове для обновления формулы, приводит к проблеме определения области - PullRequest
1 голос
/ 14 мая 2019

Я полагаюсь на пакет compareGroups для некоторых сравнений после цепочки каналов. При подстановке окончательных результатов вызов [ инициирует вызов update (оба варианта compareGroups), что приводит к проблеме с областью видимости.

Попробуйте это:

library(tidyverse)
# install.packages("compareGroups")
library(compareGroups)

get_data <- function() return(mtcars)

assign_group <- function(df) {
  n <- nrow(df)
  df$group <- rbinom(n, 1, 0.5)
  return(df)
}

get_results <- function(){
  get_data() %>% assign_group %>% compareGroups(group ~ ., data = .)
}

res <- get_results()
# all the above works, but the following triggers the error:
res["mpg"]

Это приводит к следующей ошибке:

Ошибка в CompareGroups (формула = группа ~ mpg, данные =.): объект "." не найдено

Соответствующая (сокращенная) обратная связь выглядит так:

compareGroups(formula = group ~ mpg, data = .) 
eval(call, parent.frame()) 
update.compareGroups(x, formula = group ~ mpg) 
update(x, formula = group ~ mpg) at <text>#1
eval(parse(text = cmd)) 
`[.compareGroups`(res, "mpg") 
res["mpg"] 

Итак, я понимаю, что точка-нотация в конвейере dplyr не позволяет вызову обновления найти фрейм данных, который хранится как . в вызове. Таким образом, ошибка имеет смысл, поскольку ни . не является ни именем информационного кадра, ни недоступным вне области действия функции get_results (хотя основной проблемой является .). Одним из очевидных способов избежать этой ошибки является исправление функции update.compareGroups - я не думаю, что нам нужен еще один вызов пакета, чтобы повторить все вычисления, когда я просто хочу получить отдельные результаты (которые уже были рассчитаны).

Однако это более общая проблема с . нотацией dplyr и тем фактом, что она сохраняется в вызове. Эта проблема кажется достаточно общей, чтобы я мог представить, что кто-то сталкивался с ней раньше и нашел более общее решение?

1 Ответ

0 голосов
/ 14 мая 2019

Во-первых, я не думаю, что пайпинг ваших данных в compareGroups имеет смысл - помните, что пайпинг означает, что первый аргумент compareGroups() теперь является фреймом данных, даже если спецификация функции:

compareGroups(formula, data, ...)

Во-вторых, эта виньетка dplyr показывает, что вы можете использовать .data вместо . для доступа к переданным данным.Тем не менее, в этом случае следующее вызовет сбой, выдав сообщение data argument will be ignored since formula is already a data set (из-за данных, переданных в первый аргумент).

get_results <- function(){
  get_data() %>% assign_group %>% compareGroups(group ~ ., data = .data)  # does NOT work
}

Отдельный вызов compareGroups без передачи по трубопроводу заставит меняв безобразный беспорядок сред, в которых res не имеет доступа к данным при запросе res['mpg'] вне функции get_results(), как вы уже упоминали в проблеме с областью видимости.Я думаю, что это проблема compareGroups, потому что если я использую ту же архитектуру с glm, такой проблемы не будет.Поэтому лучшее, что я могу сделать, - это вынуть фрейм данных из функциональной среды, которая, я думаю, не дает правильного ответа на ваш вопрос:

get_data <- function() return(mtcars)

assign_group <- function(df) {
    n <- nrow(df)
    df$group <- rbinom(n, 1, 0.5)
    return(df)
}
df = get_data() %>% assign_group()
res = compareGroups(group ~ ., data = df)
print(res['mpg'])

Но я надеюсь, что первые два замечания, которые я сделал, приблизят вас кответ.

...