在 dplyr 的 mutate 中使用 switch 语句 [英] Using switch statement within dplyr's mutate

查看:27
本文介绍了在 dplyr 的 mutate 中使用 switch 语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 dplyr 的 mutate 中使用 switch 语句.我有一个简单的函数,它执行一些操作并通过 switch 分配替代值,例如:

I would like to use a switch statement within dplyr's mutate. I have a simple function that performs some operations and assigns alternative values via switch, for example:

convert_am <- function(x) {
    x <- as.character(x)
    switch(x,
           "0" = FALSE,
           "1" = TRUE,
           NA)
}

当应用于标量时,这可以按需要工作:

This works as desired when applied to scalars:

>> convert_am(1)
[1] TRUE
>> convert_am(2)
[1] NA
>> convert_am(0)
[1] FALSE

我想通过 mutate 调用获得等效结果:

I would like to arrive at equivalent results via mutate call:

mtcars %>% mutate(am = convert_am(am))

这失败了:

mutate_impl(.data, dots) 中的错误:评估错误:EXPR 必须是长度为 1 的向量.

Error inmutate_impl(.data, dots) : Evaluation error: EXPR must be a length 1 vector.

我知道这是因为传递给 switch 的值不是单一的,例如:

I understand that this is because values passed to switch ar not single, as in example:

convert_am(c(1,2,2)) switch(x, 0 = FALSE, 1 = TRUE, NA) 中的错误:EXPR 必须是长度1 个向量

convert_am(c(1,2,2)) Error in switch(x, 0 = FALSE, 1 = TRUE, NA) : EXPR must be a length 1 vector

矢量化

尝试矢量化也会产生预期的结果:

Vectorization

Attempt to vectorize also yield the desired results:

convert_am <- function(x) {
    x <- as.character(x)

    fun_switch <- function(x) {
        switch(x,
               "0" = FALSE,
               "1" = TRUE,
               NA)
    }

    vf <- Vectorize(fun_switch, "x")
}

>> mtcars %>% mutate(am = convert_am(am))
Error in mutate_impl(.data, dots) : 
  Column `am` is of unsupported type function

注意事项

  • 我知道 dplyr 中的 case_when 并且我对使用它不感兴趣,我只对使 switch 在 mutate 中工作感兴趣
  • 理想的解决方案将允许进一​​步扩展以使用 mutate_at 和作为 传递的变量.
  • Notes

    • I'm aware of case_when in dplyr and I'm not interested in using it, I'm only interested in making switch work inside mutate
    • Ideal solution would allow for further expansion to use mutate_at with variables passed as .
    • 推荐答案

      switch 没有向量化,因此为了提高效率,您需要使用 ifelsecase_when - 但由于您的问题是关于 switch,您可以通过矢量化来实现您想要的,例如

      switch is not vectorized so for efficiency you need to use ifelse or case_when - but as your question is specifically about switch, you can achieve what you want by vectorizing, e.g.

      convert_am <- Vectorize(function(x) {
          x <- as.character(x)
          switch(x,
             "0" = FALSE,
             "1" = TRUE,
             NA)
      })
      

      convert_am <- function(x) {
          x <- as.character(x)
          sapply(x, function(xx) switch(xx,
             "0" = FALSE,
             "1" = TRUE,
             NA))
      }
      

      它们都效率低下,因为它们涉及到引擎盖下的循环.

      They are both inefficient as they involve a loop under the hood.

      这篇关于在 dplyr 的 mutate 中使用 switch 语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆