使用 NSE 时出错(在 dplyr 中):找不到对象“值”

丢失的

我试图熟悉在我的代码中使用 NSE 的必要条件。假设我有几对列,并且想要为每一对生成一个新的字符串变量,以指示该对中的值是否相同。

library(tidyverse)
library(magrittr)

df <- tibble(one.x = c(1,2,3,4),
             one.y = c(2,2,4,3),
             two.x = c(5,6,7,8),
             two.y = c(6,7,7,9),
             # not used but also in df
             extra = c(5,5,5,5))

我正在尝试编写可以完成与以下代码相同的事情的代码:

df.mod <- df %>%
  # is one.x the same as one.y?
  mutate(one.x_suffix = case_when( 
    one.x == one.y ~ "same",
    TRUE ~ "different")) %>%
  # is two.x the same as two.y?
  mutate(two.x_suffix = case_when(
    two.x == two.y ~ "same",
    TRUE ~ "different"))

df.mod
#> # A tibble: 4 x 6
#>   one.x one.y two.x two.y one.x_suffix two.x_suffix
#>   <dbl> <dbl> <dbl> <dbl> <chr>        <chr>       
#> 1    1.    2.    5.    6. different    different   
#> 2    2.    2.    6.    7. same         different   
#> 3    3.    4.    7.    7. different    same        
#> 4    4.    3.    8.    9. different    different

在我的实际数据中,我有任意数量的这样的对(例如three.xthree.y,...),所以我想使用mutate_at.

我的策略是在“.X”变量的传递.vars,然后gsub在‘X’上的内部平等测试的一侧‘Y’ case_when,就像这样:

df.mod <- df %>%
  mutate_at(vars(one.x, two.x),
            funs(suffix = case_when(
              . == !!sym(gsub("x", "y", deparse(substitute(.)))) ~ "same",
              TRUE ~ "different")))
#> Error in mutate_impl(.data, dots): Evaluation error: object 'value' not found.

这是我遇到异常的时候。看起来这gsub部分工作正常:

df.debug <- df %>%
  mutate_at(vars(one.x, two.x),
            funs(suffix = gsub("x", "y", deparse(substitute(.)))))
df.debug
#> # A tibble: 4 x 6
#>   one.x one.y two.x two.y one.x_suffix two.x_suffix
#>   <dbl> <dbl> <dbl> <dbl> <chr>        <chr>       
#> 1    1.    2.    5.    6. one.y        two.y       
#> 2    2.    2.    6.    7. one.y        two.y       
#> 3    3.    4.    7.    7. one.y        two.y       
#> 4    4.    3.    8.    9. one.y        two.y

这是!!sym()导致这里异常操作。我做错了什么?

reprex 包(v0.2.1)于 2018 年 11 月 7 日创建

阿尔乔姆·索科洛夫

问题不在!!sym,正如您在以下示例中看到的那样:

df %>% mutate_at( vars(one.x, two.x),
                  funs(suffix = case_when(
                    . == !!sym("one.y") ~ "same",
                    TRUE ~ "different")))
# # A tibble: 4 x 6
#   one.x one.y two.x two.y one.x_suffix two.x_suffix
#   <dbl> <dbl> <dbl> <dbl> <chr>        <chr>       
# 1     1     2     5     6 different    different   
# 2     2     2     6     7 same         different   
# 3     3     4     7     7 different    different   
# 4     4     3     8     9 different    different   

问题在于试图在substitute(.)内部取消引用case_when

df %>% mutate_at( vars(one.x, two.x),
                  funs(suffix = case_when(
                    . == !!substitute(.) ~ "same",
                    TRUE ~ "different")))
# Error in mutate_impl(.data, dots) : 
#   Evaluation error: object 'value' not found.

这样做的原因是运算符优先级。从帮助页面!!

这 !!运算符取消引用其参数。它会立即在周围的上下文中进行评估。

在上面的例子中,上下文 for!!substitute(.)是公式,它本身就在 里面case_when这导致表达式立即被替换为value,它在内部定义case_when并且在您的数据框中没有任何意义。

您希望将表达式放在他们的环境旁边,这就是quosures的用途。通过替换substituterlang::enquo,您可以捕获.与其定义环境(您的数据框)一起产生的表达式为了保持整洁,让我们将您的gsub操作移到一个单独的函数中:

x2y <- function(.x)
{
  ## Capture the expression and its environment
  qq <- enquo(.x)

  ## Retrieve the expression and deparse it
  txt <- rlang::get_expr(qq) %>% rlang::expr_deparse()

  ## Replace x with y, as before
  txty <- gsub("x", "y", txt)

  ## Put the new expression back into the quosure
  rlang::set_expr( qq, sym(txty) )
}

您现在可以x2y直接在代码中使用新函数。对于 quosures,不需要取消引用,因为表达式已经带有它们的环境;您可以简单地使用rlang::eval_tidy以下方法评估它们

df %>% mutate_at(vars(one.x, two.x),
                 funs(suffix = case_when(
                   . == rlang::eval_tidy(x2y(.)) ~ "same",
                   TRUE ~ "different" )))
# # A tibble: 4 x 6
#   one.x one.y two.x two.y one.x_suffix two.x_suffix
#   <dbl> <dbl> <dbl> <dbl> <chr>        <chr>       
# 1     1     2     5     6 different    different   
# 2     2     2     6     7 same         different   
# 3     3     4     7     7 different    same        
# 4     4     3     8     9 different    different   

编辑以解决您评论中的问题:将所有代码合并为一行几乎总是一个坏主意™,我强烈建议不要这样做。然而,由于这个问题是关于 NSE 的,我认为理解为什么简单地获取内容x2y并将其粘贴在里面case_when会导致问题是很重要的。

enquo(),如substitute(),查看函数的调用环境并将参数替换为提供给该函数的表达式。substitute()只向上一个环境(当你取消引用它时找到value里面case_when),同时enquo()只要调用堆栈中的函数正确处理quasiquotation 就会继续向上移动(大多数 dplyr/tidyverse 函数都这样做。)因此,当您调用enquo(.x)inside 时x2y,它会将提供给调用堆栈上的每个函数的表达式向上移动,最终找到one.x

当您调用enquo()inside 时mutate_at,它现在与 处于同一级别one.x,因此它也将参数(one.x在本例中)替换为定义它的表达式(c(1,2,3,4)在本例中为向量)。这不是你想要的。您现在希望保持与one.x. 为此,请使用rlang::quo()代替rlang::enquo()

library( rlang )   ## To maintain at least a little bit of sanity

df %>% 
 mutate_at(vars(one.x, two.x),
   funs(suffix = case_when(
    . == eval_tidy(set_expr(quo(.), 
                            sym(gsub("x","y", expr_deparse(get_expr(quo(.)))))
                       )
            ) ~ "same",
    TRUE ~ "different" )))
# Now works as expected

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

dplyr的filter_中的非标准评估(NSE),并从MySQL中提取数据

来自分类Dev

使用dplyr 0.3.02中的group_by将数据框分组后,选择列时出错

来自分类Dev

dplyr和非标准评估(NSE)

来自分类Dev

在函数内部使用dplyr时出错

来自分类Dev

在dplyr mutate中使用“ diff”功能时出错

来自分类Dev

NSE使用dplyr的do()处理复杂表达式

来自分类Dev

如何在dplyr函数的左侧执行NSE?

来自分类Dev

dplyr:NSE加入中(作者)

来自分类Dev

对象“。” 使用dplyr进行配管时找不到

来自分类Dev

使用sqlalchemy创建sql引擎时出错-找不到图片

来自分类Dev

使用对象分配索引值时出错

来自分类Dev

使用RVM在OSX 10.15.2 Catalina中安装Ruby 2.3.8时出错;找不到OpenSSL

来自分类Dev

使用dplyr和NSE动态构造具有不同参数的函数调用

来自分类Dev

在R中的data.table中使用NSE

来自分类Dev

用户编写的函数中存在purrr + dplyr NSE问题

来自分类Dev

创建列表标题列时在“突变”中使用dplyr :: sym()会导致错误is_symbol(x):找不到对象'.x'

来自分类Dev

找不到方法。使用Google我的商家API时出错

来自分类Dev

使用NSE构造公式

来自分类Dev

编程功能:DPLYR和PURRR中的NSE

来自分类Dev

如何使用dplyr在NSE中获取变量的名称

来自分类Dev

过滤在dplyr中创建的模型表时出错

来自分类Dev

为什么我使用SE或NSE dplyr函数得到不同的结果

来自分类Dev

函数中的dplyr NSE模式:嵌套条件

来自分类Dev

R降价错误“找不到对象'...'”,使用dplyr

来自分类Dev

如何在dplyr中使用NSE来引用一个变量?

来自分类Dev

在 dplyr::case_when 中使用 NSE

来自分类Dev

使用 ggplot 和 dplyr 绘制多个组时出错

来自分类Dev

在 dplyr 中使用重命名和汇总时出错

来自分类Dev

使用 dplyr 过滤时忽略 NA 值

Related 相关文章

  1. 1

    dplyr的filter_中的非标准评估(NSE),并从MySQL中提取数据

  2. 2

    使用dplyr 0.3.02中的group_by将数据框分组后,选择列时出错

  3. 3

    dplyr和非标准评估(NSE)

  4. 4

    在函数内部使用dplyr时出错

  5. 5

    在dplyr mutate中使用“ diff”功能时出错

  6. 6

    NSE使用dplyr的do()处理复杂表达式

  7. 7

    如何在dplyr函数的左侧执行NSE?

  8. 8

    dplyr:NSE加入中(作者)

  9. 9

    对象“。” 使用dplyr进行配管时找不到

  10. 10

    使用sqlalchemy创建sql引擎时出错-找不到图片

  11. 11

    使用对象分配索引值时出错

  12. 12

    使用RVM在OSX 10.15.2 Catalina中安装Ruby 2.3.8时出错;找不到OpenSSL

  13. 13

    使用dplyr和NSE动态构造具有不同参数的函数调用

  14. 14

    在R中的data.table中使用NSE

  15. 15

    用户编写的函数中存在purrr + dplyr NSE问题

  16. 16

    创建列表标题列时在“突变”中使用dplyr :: sym()会导致错误is_symbol(x):找不到对象'.x'

  17. 17

    找不到方法。使用Google我的商家API时出错

  18. 18

    使用NSE构造公式

  19. 19

    编程功能:DPLYR和PURRR中的NSE

  20. 20

    如何使用dplyr在NSE中获取变量的名称

  21. 21

    过滤在dplyr中创建的模型表时出错

  22. 22

    为什么我使用SE或NSE dplyr函数得到不同的结果

  23. 23

    函数中的dplyr NSE模式:嵌套条件

  24. 24

    R降价错误“找不到对象'...'”,使用dplyr

  25. 25

    如何在dplyr中使用NSE来引用一个变量?

  26. 26

    在 dplyr::case_when 中使用 NSE

  27. 27

    使用 ggplot 和 dplyr 绘制多个组时出错

  28. 28

    在 dplyr 中使用重命名和汇总时出错

  29. 29

    使用 dplyr 过滤时忽略 NA 值

热门标签

归档