r - dplyr::mutate 中的非标准评估

标签 r dplyr tidyverse

理论上这应该可行,因为我已经阅读了 NSE 上的 tidyverse 指南,但它抛出了一个错误,如本例底部所示。为什么是这样?我了解如何对一个对象进行简单的准引用,但我不了解如何评估两个准引用对象的一小部分。有人可以帮忙吗?

    tmp <- structure(list(qa11a = structure(c(1616, 7293, 1528, 1219, 2049, 286),
                                            label = "Total voters removed from Nov. 2008 to Nov. 2010",
                                            class = c("labelled","numeric")),
                          state_abbv = c("AL", "AL", "AL", "AL", "AL", "AL"),
                          fipscode = c("0100100000", "0100300000", "0100500000",
                                       "0100700000", "0100900000", "0101100000"),
                          qa1a = structure(c(34727, 114952, 16450, 12239, 31874, 7650),
                                           label = "Total registered & eligible to vote November 2010",
                                           class = c("labelled", "numeric")),
                          reg.pct = structure(c(0.0465343968669911, 0.0634438722249287,
                                                0.092887537993921, 0.0995996404935044,
                                                0.0642843697057163, 0.0373856209150327),
                                              label = "Total voters removed from Nov. 2008 to Nov. 2010",
                                              class = c("labelled", "numeric")),
                          precleared = c(1, 1, 1, 1, 1, 1),
                          year = c(2010, 2010, 2010, 2010, 2010, 2010),
                          shelby = c(0, 0, 0, 0, 0, 0), 
                          pres = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)),
                      .Names = c("qa11a", "state_abbv", "fipscode", "qa1a",
                                 "reg.pct", "precleared", "year", "shelby", "pres"),
                      row.names = c(NA, -6L),
                      class = c("tbl_df", "tbl", "data.frame"))

    require(tidyverse)
    require(rlang)

    upper="qa11a"
    lower="qa1a"
    pct.name="rej.reg"

    pct.reg <- quo_name(enquo(pct.name))
    upper <- enquo(upper)
    lower <- enquo(lower)

    h <- tmp %>%
        mutate(!! pct.reg := (!!upper)/(!!lower))

    #> Error in mutate_impl(.data, dots): Evaluation error: non-numeric argument to binary operator.

最佳答案

我们可以将字符串转换为符号然后求值

tmp %>% 
   mutate(!! pct.name := (!! sym(upper)/(!! sym(lower))))
# A tibble: 6 x 10
#  qa11a state_abbv fipscode     qa1a reg.pct precleared  year shelby pres  rej.reg
#  <dbl> <chr>      <chr>       <dbl>   <dbl>      <dbl> <dbl>  <dbl> <lgl>   <dbl>
#1  1616 AL         0100100000  34727  0.0465       1.00  2010      0 F      0.0465
#2  7293 AL         0100300000 114952  0.0634       1.00  2010      0 F      0.0634
#3  1528 AL         0100500000  16450  0.0929       1.00  2010      0 F      0.0929
#4  1219 AL         0100700000  12239  0.0996       1.00  2010      0 F      0.0996
#5  2049 AL         0100900000  31874  0.0643       1.00  2010      0 F      0.0643
#6   286 AL         0101100000   7650  0.0374       1.00  2010      0 F      0.0374

当我们在字符串上应用 enquo 时,它会转换为带引号的 quosure

enquo(upper)
# <quosure>
#  expr: ^"qa11a"
#  env:  empty

与其从字符串转换,不如这样做更容易

upper <- quo(qalla)
lower <- quo(qala)

在 OP 的代码中,调用 enquo 即在字符串对象上转换为 quosure 将导致字符串 quosure 而这不是预期的

upper <- "qa11a"
lower <- "qa1a"
enquo(upper)
#<quosure>
#  expr: ^"qa11a"
#  env:  empty

我们可以比较一下

upper <- quo(qa11a)
lower <- quo(qa1a)
upper
# <quosure>
#  expr: ^qalla
#  env:  global

并执行它

tmp %>% 
     mutate(!! pct.name := (!! upper)/ (!! lower))
# A tibble: 6 x 10
#  qa11a state_abbv fipscode     qa1a reg.pct precleared  year shelby pres  rej.reg
#  <dbl> <chr>      <chr>       <dbl>   <dbl>      <dbl> <dbl>  <dbl> <lgl>   <dbl>
#1  1616 AL         0100100000  34727  0.0465       1.00  2010      0 F      0.0465
#2  7293 AL         0100300000 114952  0.0634       1.00  2010      0 F      0.0634
#3  1528 AL         0100500000  16450  0.0929       1.00  2010      0 F      0.0929
#4  1219 AL         0100700000  12239  0.0996       1.00  2010      0 F      0.0996
#5  2049 AL         0100900000  31874  0.0643       1.00  2010      0 F      0.0643
#6   286 AL         0101100000   7650  0.0374       1.00  2010      0 F      0.0374

关于r - dplyr::mutate 中的非标准评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49882794/

相关文章:

r - 计算R中不同ID长度的个体组的两个坐标列之间的距离

r - 具有多个 (x,y) 对的数据框的高格式

r - 如何从多个data.frame中获取特定列并将其保存为R中的新data.frame?

r - ggplot2:如何以特定角度旋转图表?

java - 通过 Java 程序与 R 交互

将 NA 替换为之前出现的位置

css - 如何让 pkgdown 代码块具有深色背景?

r - ifelse 具有多个条件,用于在 data.table R 中创建新变量

r - 为什么表达式 LHS 中的 `rlang::sym` 和 `rlang::quo_name` 表现相似?

替换 dplyr 链所有列中的 NA