dplyr :: mutate中的非标准eval [英] Non-standard eval in dplyr::mutate

查看:77
本文介绍了dplyr :: mutate中的非标准eval的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In theory this should work, as I've read the tidyverse guide on NSE, but it throws me an error as seen in the bottom of this example. Why is this? I understand how to do a simple quasiquotation of an object, but I do not understand how to evaluate a fraction of two quasiquoted objects. Can anyone help with this?

    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.


推荐答案

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

We can convert the string to symbol and then evaluate

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 在字符串上,它转换为带引号的单价货币


when we apply enquo on a string, it is converting to a quosure with quotes

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

从字符串转换,这样做会更容易

Instead of converting from a string, it could be easier to do

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

在OP的代码中,调用 enquo ,即在字符串对象上转换为quasure会导致字符串quosure,这不是故意的。

In the OP's code, calling enquo i.e. converting to quosure on a string object will result in string quosure and that is not intended

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

这篇关于dplyr :: mutate中的非标准eval的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆