Отменить цитату вне контекста квази-цитаты - PullRequest
1 голос
/ 14 июня 2019

Я определяю функцию для получения прогнозируемых значений регрессионной модели с данными опроса для разных подгрупп (подгрупп). Я использую функцию svyglm из пакета опроса.

Моя проблема связана с обработкой опции subset в функции svyglm. Поскольку он использует нестандартную оценку, я понимаю, что он не принимает имена столбцов в виде строки. Я попытался просто использовать имя столбца без строк и заключить в кавычки (enquo) и удалить его (!!). Однако оба варианта не работают. Я также играл с ensym () и expr (), но не получил никаких результатов.

Данные и библиотека

library(dplyr)
library(survey)
library(srvyr)
library(purrr)
library(rlang)

mtcars <- read.table("https://forge.scilab.org/index.php/p/rdataset/source/file/master/csv/datasets/mtcars.csv",
                     sep=",", header=TRUE)

mtcars_cplx <- mtcars %>% as_survey_design(id = cyl, weights = qsec)

carb <- c(1:8)
cyl <- c(4:8)
new_data <- expand.grid(carb, cyl)
colnames(new_data) <- c("carb", "cyl")

С вопросом

Функция и вход

subpop_pred <- function(formula, data, subpop, new_data) {

  subpop_quo <- enquo(subpop)
  subpop_txt <- data$variables %>% select(!!subpop_quo) %>% colnames()

  for(i in min(data$variables[subpop_txt]):max(data$variables[subpop_txt])){
    reg <- svyglm(formula, data, subset=!!subpop_quo==i)
    pred <- predict(reg, newdata=new_data)

    if(exists("reg_end")==TRUE){
      pred <- cbind(new_data, pred, confint(pred))
      pred[subpop_txt] <- i
      reg_end <- rbind(reg_end, pred)
    } else {
      reg_end <- cbind(new_data, pred, confint(pred))
      reg_end[subpop_txt] <- i
    }
  }
}

subpop_pred(mpg ~ carb + cyl + carb*cyl, 
            data=mtcars_cplx, 
            new_data=new_data,
            subpop=gear)

Выход / Error

 Error: Base operators are not defined for quosures.
Do you need to unquote the quosure?

  # Bad:
  myquosure == rhs

  # Good:
  !!myquosure == rhs
Call `rlang::last_error()` to see a backtrace 
8. stop(cnd) 
7. abort(paste_line("Base operators are not defined for quosures.", 
    "Do you need to unquote the quosure?", "", "  # Bad:", bad, 
    "", "  # Good:", good, )) 
6. Ops.quosure(subpop_quo, i) 
5. eval(subset, model.frame(design), parent.frame()) 
4. eval(subset, model.frame(design), parent.frame()) 
3. svyglm.survey.design(formula, data, subset = !!subpop_quo == 
    i) 
2. svyglm(formula, data, subset = !!subpop_quo == i) 
1. subpop_pred(mpg ~ carb + cyl + carb * cyl, data = mtcars_cplx, 
    new_data = new_data, subpop = gear) 

Без выдержки

Функция и вход

subpop_pred <- function(formula, data, subpop, new_data) {

  subpop_quo <- enquo(subpop)
  subpop_txt <- data$variables %>% select(!!subpop_quo) %>% colnames()

  for(i in min(data$variables[subpop_txt]):max(data$variables[subpop_txt])){
    reg <- svyglm(formula, data, subset=subpop==i)
    pred <- predict(reg, newdata=new_data)

    if(exists("reg_end")==TRUE){
      pred <- cbind(new_data, pred, confint(pred))
      pred[subpop_txt] <- i
      reg_end <- rbind(reg_end, pred)
    } else {
      reg_end <- cbind(new_data, pred, confint(pred))
      reg_end[subpop_txt] <- i
    }
  }
}

subpop_pred(mpg ~ carb + cyl + carb*cyl, data=mtcars_cplx, new_data=new_data, subpop=gear)

выход

Error in eval(subset, model.frame(design), parent.frame()) : 
  object 'gear' not found 
5. eval(subset, model.frame(design), parent.frame()) 
4. eval(subset, model.frame(design), parent.frame()) 
3. svyglm.survey.design(formula, data, subset = subpop == i) 
2. svyglm(formula, data, subset = subpop == i) 
1. subpop_pred(mpg ~ carb + cyl + carb * cyl, data = mtcars_cplx, 
    new_data = new_data, subpop = gear) 

У вас есть идея, как заставить функцию работать?

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Я мог бы заставить вещи работать с аргументом subset, смешав expr() и rlang::tidy_eval().

Строка модели в вашей функции может выглядеть так:

reg <- svyglm(formula, data = data, 
       subset = rlang::eval_tidy( expr( !!subpop_quo == i), data =  data) )

Я не знаю, надежный это, хотя, или есть какой-то более простой подход к tidyeval. Работа над этим заставила меня понять, что с функцией / аргументом subset() трудно работать в функциях. : -Р

0 голосов
/ 17 июня 2019

Не уверен, что есть лучший способ сделать это, поскольку svyby(), похоже, не поддерживает svyglm().Здесь quo_squash() используется для передачи выражений в subset().Это может быть расширено, чтобы сделать предсказания.

gears = unique(mtcars$gear)
lapply(gears, function(x) {
  subset(mtcars_cplx, !!quo_squash(gear == x)) %>% 
    svyglm(mpg ~ carb + cyl + carb*cyl, design = .)
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...