首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >do.call()与整齐评价

do.call()与整齐评价
EN

Stack Overflow用户
提问于 2017-12-29 16:22:50
回答 3查看 1.1K关注 0票数 6

试图使do.call()在整洁的评估环境中工作:

代码语言:javascript
复制
library(rlang)
library(dplyr)

data <- tibble(item_name = c("apple", "bmw", "bmw"))

mutate(data, category = case_when(item_name == "apple" ~ "fruit",
                                  item_name == "bmw" ~ "car"))

# # A tibble: 3 x 2
#   item_name category
#   <chr>     <chr>   
# 1 apple     fruit   
# 2 bmw       car     
# 3 bmw       car 

以下两者的不同之处:

代码语言:javascript
复制
category_fn <- function(df, ...){
  # browser()
  cat1 <- quos(...)
  mutate(df, category = case_when(!!! cat1))
}

category_fn(df = data, item_name == "apple" ~ "fruit",
                       item_name == "bmw" ~ "car")

# # A tibble: 3 x 2
#   item_name category
#   <chr>     <chr>   
# 1 apple     fruit   
# 2 bmw       car     
# 3 bmw       car 

以及:

代码语言:javascript
复制
cat <- list(item_name == "apple" ~ "fruit", item_name == "bmw" ~ "car")

do.call(category_fn, c(list(df = data), cat), quote = FALSE)
# Or:
do.call(category_fn, c(list(df = data), cat), quote = TRUE)
# Or:
rlang::invoke(category_fn, c(list(df = data), cat))

所有这些都会产生相同的错误:

代码语言:javascript
复制
# Error in mutate_impl(.data, dots) : 
#   Evaluation error: object 'item_name' not found.

我使用browser()进入了函数,检查了参数,在那里运行了expr(mutate(df, category = case_when(!!! cat1))) (这是http://rpubs.com/lionel-/programming-draft中的通用调试策略),在这两种情况下都有相同的输出:mutate(df, category = case_when(~(item_name == "apple" ~ "fruit"), ~(item_name == "bmw" ~ "car")))

我还试图调整envir.env参数,但没有效果。

我的理解是,这可能与不同的质量环境有关,但environment(cat1[[1]])也是相同的(<environment: R_GlobalEnv>)。

注意:

不知何故,这是我试图回答的什么时候的后续行动。

代码语言:javascript
复制
> sessioninfo::session_info()
─ Session info ────────────────────────────────────────────────────────
 setting  value                       
 version  R version 3.4.3 (2017-11-30)
 os       Linux Mint 18               
 system   x86_64, linux-gnu           
 [...]                 

─ Packages ────────────────────────────────────────────────────────────
 package     * version    date       source                             
 [...]                
 dplyr       * 0.7.4      2017-09-28 CRAN (R 3.4.3)                     
 [...]                    
 rlang       * 0.1.6      2017-12-21 CRAN (R 3.4.3)                     
 [...]
EN

回答 3

Stack Overflow用户

发布于 2017-12-29 17:15:34

我们可以将“cat”创建为quosure,然后使用!!!进行评估

代码语言:javascript
复制
cat <-  quos(item_name == "apple" ~ "fruit", item_name == "bmw" ~ "car")
category_fn(data, !!!(cat))
# A tibble: 3 x 2
#  item_name category
#  <chr>     <chr>   
#1 apple     fruit   
#2 bmw       car     
#3 bmw       car    
票数 3
EN

Stack Overflow用户

发布于 2017-12-29 17:25:19

我认为这与另一篇文章类似;引用列表本身并不等于单独引用列表中的元素。

我修改了cat定义以单独引用元素,并稍微修改了函数,以删除quosure语句并显式命名参数。在do.call语句(第二个参数,要提供给函数的参数列表)中,我将cat元素作为列表的一部分包括在内。

通过这些修改,两个do.call语句和invoke将返回与post中的直接执行相同的结果:

代码语言:javascript
复制
data <- tibble(item_name = c("apple", "bmw", "bmw"))

cat <- list(quo(item_name == "apple" ~ "fruit"), 
            quo(item_name == "bmw" ~ "car"))

category_fn <- function(df, category){
  mutate(df, category = case_when(!!! category))
}

> do.call(category_fn, list(data, cat), quote = FALSE)
# A tibble: 3 x 2
  item_name category
      <chr>    <chr>
1     apple    fruit
2       bmw      car
3       bmw      car
> # Or:
> do.call(category_fn, list(data, cat), quote = TRUE)
# A tibble: 3 x 2
  item_name category
      <chr>    <chr>
1     apple    fruit
2       bmw      car
3       bmw      car
> # Or:
> rlang::invoke(category_fn, list(df = data, cat))
# A tibble: 3 x 2
  item_name category
      <chr>    <chr>
1     apple    fruit
2       bmw      car
3       bmw      car

引号参数的值在两个do.call示例中没有区别。

我发现商在概念上是困难的,并且没有使当前的用dplyr编程在Cran上变得更容易。

票数 2
EN

Stack Overflow用户

发布于 2017-12-29 23:29:29

我对什么时候的回应的第(1a)部分中的答案也在这里起作用。

如果catdatacategory_fn与本问题相同,那么这是可行的。第一行将cat转换为cat_,这是一个在这里工作的表单。

代码语言:javascript
复制
cat_ <- lapply(cat, function(x) do.call("substitute", list(x))) 
do.call("category_fn", c(list(df = data), cat_))

给予:

代码语言:javascript
复制
# A tibble: 3 x 2
  item_name category
      <chr>    <chr>
1     apple    fruit
2       bmw      car
3       bmw      car

关于结尾的问题-在我对原来问题的答复中,似乎要求用商的替代办法-我已将上述问题联系起来-是使用wrapr包和基R解决该问题的办法。作者wrapr的seplyr包也可能是一个备选办法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48025432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档