与dplyr混合报价

时间:2019-03-15 14:43:17

标签: r functional-programming dplyr purrr quasiquotes

我已经将准报价提高到了最高水平。 我快要拿到我的准准价格大师证章(请参见下面的修改)。还剩下一个挑战。

使用不同的输入来创建dplyr的定量。最终结果是:

the_quote <- quo( if_else(!!cond_expr, !!inter_quo, !!var_expr) )

而且我已经成功地使用字符串从自定义表构造了上面的表达式,像这样:

var_expr <- as.name(rules_df$target_col)

cond_expr <- "make == '%s'" %>% sprintf(rules_df$context_col) %>% parse_expr()

inter_quo <- quo( 
    str_detect( !!var_expr, regex(!!rules_df$phrase_col) ))

其中context_colphrase_coltarget_col是我定义了参与规则的表中的字符串列。

示例:

rules_df <- data_frame(
    context_col = "BMW", 
    phrase_col  = "Serie X(\\d)", 
    target_col  = "model")

cars_table <- data_frame(
    make = c("Mercedes", "BMW", "BMW"), 
    model = c("Viano", "Serie X5", "Z4"))

告诉我找到那些Serie X5的宝马,后来我将其替换为X5,但这是另一个故事。

在打印报价时,我注意到这些表达式可以很好地工作,但是中间的定额却给出了一个错误。

> the_quote
<quosure>
  expr: ^if_else(marca == "BMW", 
            ^str_detect(model, regex("Serie X(\d)")), model)
  env:  000000002001DEE0

> mutate(cars_table, detect = !!the_quote)
Error: Evaluation error: `false` must be type logical, not character.

在Ququoise中,我有一个额外的^,它将str_detect的结果转换为字符。

我如何将这种中间环境整合到外部环境中?

谢谢。

编辑

在查看解决方案后,最终得出的结论是,此挑战中的问题不是报价,而是在if_else列中正确使用了detect。那就是将逻辑变成字符,或者只是使false子句相应地起作用。

因此,替代解决方案是从一开始就设置if_else(!!cond_expr, !!inter_quo, FALSE)

1 个答案:

答案 0 :(得分:1)

我们需要用as.character包装,因为str_detect返回逻辑类,而false的{​​{1}}参数返回'character'。 if_else是关于类的。因此,如果我们这样做

if_else

然后它应该工作

inter_quo <- quo( as.character(str_detect( !!var_expr, 
               regex(!!rules_df$phrase_col) )))