将数值传递到函数内的if{}语句中的管道dplyr动词。

huangapple go评论61阅读模式
英文:

pass values through to piped dplyr verb inside if{} statement in function

问题

以下是您要翻译的内容:

假设我有以下数据:

d <- msleep %>%
mutate(comfort_color_desk = sample(c(0,1), replace=TRUE, size=nrow(msleep)),
comfort_color_chair = sample(c(0,1), replace=TRUE, size=nrow(msleep)))


我想将它传递给一个位于我制作的函数内部的 `dplyr` 链,该函数还包括一个触发链内的 `{if}` 子句的指示器。

例如(这可以正常工作):

```R
test_fcn &lt;- function(.x, .y, .count = NULL) {
  .x %&gt;% select(order, .y) %&gt;%
    {if(isTRUE(.count)) count(.,!!ensym(.y)) else .} 
}

d %&gt;% test_fcn(., .y = &quot;comfort_color_desk&quot;, .count = TRUE)

这显示了我想要做的基本原理。我面临的问题是当我想要仅传递部分列名并将其与字符串连接并将其评估为函数内的数据列时。

例如(这不起作用):

test_2_fcn &lt;- function(.x, .y, .z, .compare = NULL) {
  .x %&gt;% 
    {if(isTRUE(.compare)) filter(., paste0(&quot;comfort_color_&quot;, !!ensym(.y)) == 1 &amp; paste0(&quot;comfort_color&quot;, !!ensym(.z)) == 1) else .} 
}

d %&gt;% test_2_fcn(., .y = &quot;desk&quot;, .z = &quot;chair&quot;, .compare = TRUE)

我怀疑这是与整洁评估(tidy evaluation)有关的问题。请问是否有人可以指导我正确的方向?


<details>
<summary>英文:</summary>

Say I have this data:

d <- msleep %>%
mutate(comfort_color_desk = sample(c(0,1), replace=TRUE, size=nrow(msleep)),
comfort_color_chair = sample(c(0,1), replace=TRUE, size=nrow(msleep)))


I want to pass it through to a `dplyr` chain that lives inside a function i&#39;ve made, which also includes an indicator to trigger an `{if}` clause inside of the chain. 

For example (this works just fine):

test_fcn <- function(.x, .y, .count = NULL) {
.x %>% select(order, .y) %>%
{if(isTRUE(.count)) count(.,!!ensym(.y)) else .}
}

d %>% test_fcn(., .y = "comfort_color_desk", .count = TRUE)


This shows the basic principle of what I want to do. The problem i&#39;m facing is when I want to just pass through a part of column name and `paste` that with a string and evaluate it as a data column inside the function. 

For example (this does not work):

test_2_fcn <- function(.x, .y, .z, .compare = NULL) {
.x %>%
{if(isTRUE(.compare)) filter(., paste0("comfort_color_", !!ensym(.y)) == 1 & paste0("comfort_color", !!ensym(.z)) == 1) else .}
}

d %>% test_2_fcn(., .y = "desk", .z = "chair", .compare = TRUE)


I suspect this is a problem with tidy evaluation. Can anyone point in the right direction here please? 

</details>


# 答案1
**得分**: 1

这是关于整洁评估的一个问题。`paste0`函数在`!!ensym()`之前被评估,所以现在尝试将文字字符串`"comfort_color_"`与符号`.y`或`.z`连接在一起,而不是它们的值。

我们可以使用`sym()`函数将字符串转换为符号,然后使用`paste()`来连接这些字符串。

```R
library(dplyr)

test_2_fcn <- function(.x, .y, .z, .compare = NULL) {
  .x %>%
    {if(isTRUE(.compare)) filter(., !!sym(paste0("comfort_color_", .y)) == 1 & !!sym(paste0("comfort_color_", .z)) == 1) else .} 
}

d %>% test_2_fcn(., .y = "desk", .z = "chair", .compare = TRUE)
英文:

This is an issue of tidy evaluation. paste0 function is being evaluated before the !!ensym() is evaluated, now it is tried to paste the literal string &quot;comfort_color_&quot; with the symbol .y or .z instead of the values.

We could use the sym() function to convert the string to a symbol and then use paste() to concatenate the strings together.

library(dplyr)

test_2_fcn &lt;- function(.x, .y, .z, .compare = NULL) {
  .x %&gt;% 
    {if(isTRUE(.compare)) filter(., !!sym(paste0(&quot;comfort_color_&quot;, .y)) == 1 &amp; !!sym(paste0(&quot;comfort_color_&quot;, .z)) == 1) else .} 
}

d %&gt;% test_2_fcn(., .y = &quot;desk&quot;, .z = &quot;chair&quot;, .compare = TRUE)

huangapple
  • 本文由 发表于 2023年3月31日 03:21:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75892191.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定