首页 > 解决方案 > quosures、unquoting、mutate 和 ifelse

问题描述

我正在尝试使用 tidyverse 编写函数,但我被 quosures 绊倒了。

错误:mutate()输入有问题field_name。x 没有为 quosures 定义基本运算符。你需要取消报价吗?

这是一个精简的示例,除了说明问题之外没有太多作用。

library(tidyverse)

scaleSheet <- structure(list(scale_name = c("sdq", "sdq2"), 
                             scale_label = c("My fancy scale, adolescent report", 
                                             "The AWESOME scale"), 
                             totals = c("average", "sum"), items = c(4, 2), 
                             max_missing = c(1, 0), higher_is = c("\"+\"", "\"-\""), 
                             missing = c(TRUE, TRUE), 
                             impute = c("none", "none")), 
                        row.names = c(NA, -2L), class = c("tbl_df", 
                                                          "tbl", "data.frame"))

itemSheet <- structure(list(field_name = c("dfcs_sdq2", "dfcs_sdq3", "dfcs_sdq5", 
                                           "dfcs_sdq6", "dfcs_sdq2", "dfcs_sdq3"), 
                            scale_name = c("sdq", "sdq", "sdq", "sdq", "sdq2", 
                                           "sdq2"), 
                            reverse = c(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)), 
                       row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
                                                         "data.frame"))

scaleSheet
## A tibble: 2 x 8
#  scale_name scale_label        totals items max_missing higher_is missing impute
#  <chr>      <chr>              <chr>  <dbl>       <dbl> <chr>     <lgl>   <chr> 
#1 sdq        My fancy scale, a… avera…     4           1 "\"+\""   TRUE    none  
#2 sdq2       The AWESOME scale  sum        2           0 "\"-\""   TRUE    none 

itemSheet
## A tibble: 6 x 3
#  field_name scale_name reverse
#  <chr>      <chr>      <lgl>  
#1 dfcs_sdq2  sdq        FALSE  
#2 dfcs_sdq3  sdq        FALSE  
#3 dfcs_sdq5  sdq        TRUE   
#4 dfcs_sdq6  sdq        FALSE  
#5 dfcs_sdq2  sdq2       FALSE  
#6 dfcs_sdq3  sdq2       FALSE

scoreAll <- function (itemSheet, scaleSheet,
                      reverse = reverse,
                      variable = field_name,
                      scale = scale_name) {

  scale <- enquo(scale)
  variable <- enquo(variable)
  reverse <- enquo(reverse)
  
  # get list of scales
  scales <- scaleSheet %>%
    distinct(!!scale) %>%
    pull(!!scale)
  
  # loop through scales
  results <- NULL
  
  for (s in scales) {
    # get items
    items <- itemSheet %>% 
      mutate(!!variable := ifelse(!!reverse==TRUE,
                                  paste0("-", !!variable), 
                                  !!variable)) %>%
      filter(!!scale==s) %>%
      pull(!!variable)
    
    results <- c(results, items)
  }
}

scoreAll(scaleSheet, itemSheet)

标签: rtidyeval

解决方案


调用时参数的顺序颠倒了,这导致列“reverse”被查看为“scaleSheet”而不是“itemSheet”

 scoreAll <- function (itemSheet, scaleSheet,
                          reverse = reverse,
                          variable = field_name,
                          scale = scale_name) {

      scale <- enquo(scale)
      variable <- enquo(variable)
      reverse <- enquo(reverse)
  
      # get list of scales
      scales <- scaleSheet %>%
        distinct(!!scale) %>%
        pull(!!scale)
  
      # loop through scales
      results <- NULL
  
      for (s in scales) {
        # get items
        items <- itemSheet %>% 
          mutate(!!variable := ifelse(!!reverse==TRUE,
                                      paste0("-", !!variable), 
                                      !!variable)) %>%
          filter(!!scale==s) %>%
          pull(!!variable)
    
        results <- c(results, items)
      }
      results
    }

-测试

scoreAll(itemSheet, scaleSheet)
#[1] "dfcs_sdq2"  "dfcs_sdq3"  "-dfcs_sdq5" "dfcs_sdq6"  "dfcs_sdq2"  "dfcs_sdq3" 

    

推荐阅读