首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >case_when评估

case_when评估
EN

Stack Overflow用户
提问于 2020-05-04 21:18:50
回答 2查看 478关注 0票数 3

在某种程度上与Tidy evaluation programming with dplyr::case_whenMaking tidyeval function inside case_when有关,我希望创建字符串(使用一个闪亮的应用程序),以便稍后在case_when函数中进行解析。下面是一个例子:

代码语言:javascript
复制
library(tidyverse)

# simulated shiny inputs
new_column = sym("COL_NAME")

number_of_categories = 3

col1_text = "Big"
col1_min = 7.0
col1_max = 8.0

col2_text = "Medium"
col2_min = 5.0
col2_max = 6.9

col3_text = "Small"
col3_max = 4.9
col3_min = 4.0

columninput = sym("Sepal.Length")

期望输出

代码语言:javascript
复制
iris %>%
  mutate(new_column =
           case_when(
             !!columninput >= col1_min & !!columninput <= col1_max ~ col1_text,
             !!columninput  >= col2_min & !!columninput <= col2_max ~ col2_text,
             !!columninput  >= col3_min & !!columninput <= col3_max ~ col3_text
           )
  )

因为函数之间唯一的变化是索引,所以我想我们可以使用通用模式来创建一个字符串。

代码语言:javascript
复制
# create single string
my_string <-function(i) {
  paste0("!!", columninput, " >= col", i, "_min & ", "!!", columninput, " <= col", i, "_max ~ col", i, "_text")
}

然后对动态案例数重复字符串。

代码语言:javascript
复制
mega_string <- map_chr(1:number_of_categories, ~ my_string(.x))

TODO:

这是我不能完全拼凑在一起的部分:使用这些字符串作为case_when中的参数。

代码语言:javascript
复制
# evaluate somehow?
iris %>%
  mutate(
    new_column = case_when(
      # tidyeval mega_string?
      paste(mega_string, collapse = "," )
      )
    )

这就是正确的方法吗?否则,你将如何着手解决这一问题-任何帮助高水平或其他方面都是非常感谢的!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-04 21:26:32

我们可以创建一个表达式并计算

代码语言:javascript
复制
library(dplyr)
library(stringr)
iris %>% 
   mutate(new_column = eval(rlang::parse_expr(str_c('case_when(', 
          str_c(mega_string, collapse=","), ')'))))
#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species new_column
#1            5.1         3.5          1.4         0.2     setosa     Medium
#2            4.9         3.0          1.4         0.2     setosa      Small
#3            4.7         3.2          1.3         0.2     setosa      Small
#4            4.6         3.1          1.5         0.2     setosa      Small
#5            5.0         3.6          1.4         0.2     setosa     Medium
#6            5.4         3.9          1.7         0.4     setosa     Medium
#7            4.6         3.4          1.4         0.3     setosa      Small
#8            5.0         3.4          1.5         0.2     setosa     Medium
#9            4.4         2.9          1.4         0.2     setosa      Small
#10           4.9         3.1          1.5         0.1     setosa      Small
# ...

或者将parse_expr!!!结合使用

代码语言:javascript
复制
library(purrr)
iris %>%
   mutate(new_column = case_when(!!! map(mega_string, rlang::parse_expr)))
#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species new_column
#1            5.1         3.5          1.4         0.2     setosa     Medium
#2            4.9         3.0          1.4         0.2     setosa      Small
#3            4.7         3.2          1.3         0.2     setosa      Small
#4            4.6         3.1          1.5         0.2     setosa      Small
#5            5.0         3.6          1.4         0.2     setosa     Medium
#6            5.4         3.9          1.7         0.4     setosa     Medium
#7            4.6         3.4          1.4         0.3     setosa      Small
#8            5.0         3.4          1.5         0.2     setosa     Medium
#...
票数 3
EN

Stack Overflow用户

发布于 2020-10-04 07:13:44

很好的问题和答案。我使用的是相同的上下文(闪亮)。

我想提到另一种更适合我需要的方法,它更容易理解逻辑:而不是传递要计算的字符串中的变量,而是直接传递来自tibble和str_glue_data的字符串中的值。

代码语言:javascript
复制
mega <- tribble(
    ~min, ~max, ~size,
    7, 8, "Big", 
    5, 6.9, "Medium",
    4.9, 4, "Small"
) %>% 
    str_glue_data("Sepal.Length >= {min} & Sepal.Length <= {max} ~ '{size}'")

iris %>% 
    mutate(new_column = case_when(!!! map(mega, rlang::parse_expr)))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61601797

复制
相关文章

相似问题

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