【问题标题】:passing a vector into case_when inside mutate_at在 mutate_at 中将向量传递给 case_when
【发布时间】:2018-11-04 00:15:33
【问题描述】:

我想使用相同的通用mutate 创建三个新变量(称为onetwothree),但在mutate 中使用不同的现有变量。为此,我想编写一个简短的代码块,它完成与以下(详细)代码相同的事情:

mtcars.modified <- mtcars %>%

  mutate(one = factor(case_when(
    mpg < 10 ~ "lt10",
    mpg >= 10 & mpg <= 20 ~ "10to20",
    mpg > 20 ~ "gt20"),
    ordered=T, levels = c("lt10", "10to20", "gt20"))) %>%

  mutate(two = factor(case_when(
    disp < 10 ~ "lt10",
    disp >= 10 & disp <= 20 ~ "10to20",
    disp > 20 ~ "gt20"),
    ordered=T, levels = c("lt10", "10to20", "gt20"))) %>%

  mutate(three = factor(case_when(
    qsec < 10 ~ "lt10",
    qsec >= 10 & qsec <= 20 ~ "10to20",
    qsec > 20 ~ "gt20"),
    ordered =T, levels = c("lt10", "10to20", "gt20")))

我可以概括这一点的一种方法是使用mutate_at 的后缀行为,然后重命名:

mtcars.modified <- mtcars %>%
  mutate_at(c("mpg", "disp", "qsec"),
            funs(mod = factor(case_when(
              . < 10 ~ "lt10",
              . >= 10 & . <= 20 ~ "10to20",
              . > 20 ~ "gt20"),
              ordered =T, levels = c("lt10", "10to20", "gt20")))) %>%
  rename(one = mpg_mod,
         two = disp_mod,
         three = qsec_mod)

不过,这感觉像是一种解决方法。有没有办法我可以做到这一点而无需rename 之后?我想知道是否可以将onetwothree 作为.vars,然后以某种方式将第二组变量传递给case_when。这感觉类似于map2 问题,您有两个对应的向量和一个函数,该函数成对地从两个向量中获取项目。

这是我(失败的)尝试在 funs 参数中使用 map2

mtcars.modified <- mtcars %>%
  mutate_at(c("one", "two", "three"),
            funs(map2(.x = ., .y = c(mpg, disp, qsec), 
                      ~ factor(case_when(
                        .y < 10 ~ "lt10",
                        .y >= 10 & .y <= 20 ~ "10to20",
                        .y > 20 ~ "gt20"),
                        ordered =T, levels = c("lt10", "10to20", "gt20")))))

我想将所有内容保存在 mtcars %&gt;% 管道中,而不创建命名函数或破坏管道。

【问题讨论】:

    标签: r purrr dplyr


    【解决方案1】:

    如果您使用dplyr::vars 函数,您可以在应用函数之前重命名。

    mtcars %>%
      mutate_at(
        vars(one = mpg, two = disp, three = qsec),
        funs(
          case_when(
            . < 10 ~ 'lt10',
            . >= 10 & . <= 20 ~ "10to20",
            . > 20 ~ 'gt20'
          ) %>%
            ordered(levels = c('lt10', '10to20', 'gt20'))
        )
      )
    

    这也适用于@seisdrum 使用base::cut 的好建议

    mtcars %>%
      mutate_at(
        vars(one = mpg, two = disp, three = qsec),
        cut,
        breaks = c(-Inf, 10, 20, Inf),
        labels = c("lt10", "10to20", "gt20")
      )
    

    【讨论】:

      【解决方案2】:
      library(tidyverse)
      mtcars %>%
        dplyr::mutate_at(c("mpg", "disp", "qsec"), cut,
                         breaks = c(-Inf, 10, 20, Inf),
                         labels = c("lt10", "10to20", "gt20")) %>%
        head()
      #>      mpg cyl disp  hp drat    wt   qsec vs am gear carb
      #> 1   gt20   6 gt20 110 3.90 2.620 10to20  0  1    4    4
      #> 2   gt20   6 gt20 110 3.90 2.875 10to20  0  1    4    4
      #> 3   gt20   4 gt20  93 3.85 2.320 10to20  1  1    4    1
      #> 4   gt20   6 gt20 110 3.08 3.215 10to20  1  0    3    1
      #> 5 10to20   8 gt20 175 3.15 3.440 10to20  0  0    3    2
      #> 6 10to20   6 gt20 105 2.76 3.460   gt20  1  0    3    1
      

      您可以使用cut function 来完成此任务。这符合您的要求吗?

      如果您想保留原始列并且需要在修改后的列中添加后缀_mod,您可以这样做:

      library(tidyverse)
      mtcars %>%
        dplyr::mutate_at(c("mpg", "disp", "qsec"),
                         dplyr::funs(
                           mod = cut(.,
                                     breaks = c(-Inf, 10, 20, Inf),
                                     labels = c("lt10", "10to20", "gt20")
                                     )
                           )
                         ) %>%
        head()
      #>    mpg cyl disp  hp drat    wt  qsec vs am gear carb mpg_mod disp_mod
      #> 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4    gt20     gt20
      #> 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4    gt20     gt20
      #> 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1    gt20     gt20
      #> 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1    gt20     gt20
      #> 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2  10to20     gt20
      #> 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1  10to20     gt20
      #>   qsec_mod
      #> 1   10to20
      #> 2   10to20
      #> 3   10to20
      #> 4   10to20
      #> 5   10to20
      #> 6     gt20
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-09
        • 2015-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-16
        • 1970-01-01
        相关资源
        最近更新 更多