【问题标题】:Create multiple columns based on the same condition根据相同的条件创建多个列
【发布时间】:2021-02-16 10:01:07
【问题描述】:

当我们想根据一个条件改变几个新列时,有没有办法避免重复代码?

例如,在mtcars 数据集中,我想创建两个新列。一列将分类汽车是否“经济”,另一列将描述每辆车获得的“标签”的颜色。

library(dplyr)

mtcars %>%
  select(mpg, am) %>%
  mutate(economic = case_when(mpg <= 17 & am == 0 ~ "no",
                              mpg > 17 & am == 1 ~ "yes"),
         
         label = case_when(mpg <= 17 & am == 0 ~ "red",
                           mpg > 17 & am == 1 ~ "green")) 

#>                      mpg am economic label
#> Mazda RX4           21.0  1      yes green
#> Mazda RX4 Wag       21.0  1      yes green
#> Datsun 710          22.8  1      yes green
#> Hornet 4 Drive      21.4  0     <NA>  <NA>
#> Hornet Sportabout   18.7  0     <NA>  <NA>
#> Valiant             18.1  0     <NA>  <NA>
#> Duster 360          14.3  0       no   red
#> Merc 240D           24.4  0     <NA>  <NA>
#> Merc 230            22.8  0     <NA>  <NA>
#> Merc 280            19.2  0     <NA>  <NA>
#> Merc 280C           17.8  0     <NA>  <NA>
#> Merc 450SE          16.4  0       no   red
#> Merc 450SL          17.3  0     <NA>  <NA>
#> Merc 450SLC         15.2  0       no   red
#> Cadillac Fleetwood  10.4  0       no   red
#> Lincoln Continental 10.4  0       no   red
#> Chrysler Imperial   14.7  0       no   red
#> Fiat 128            32.4  1      yes green
#> Honda Civic         30.4  1      yes green
#> Toyota Corolla      33.9  1      yes green
#> Toyota Corona       21.5  0     <NA>  <NA>
#> Dodge Challenger    15.5  0       no   red
#> AMC Javelin         15.2  0       no   red
#> Camaro Z28          13.3  0       no   red
#> Pontiac Firebird    19.2  0     <NA>  <NA>
#> Fiat X1-9           27.3  1      yes green
#> Porsche 914-2       26.0  1      yes green
#> Lotus Europa        30.4  1      yes green
#> Ford Pantera L      15.8  1     <NA>  <NA>
#> Ferrari Dino        19.7  1      yes green
#> Maserati Bora       15.0  1     <NA>  <NA>
#> Volvo 142E          21.4  1      yes green

reprex package (v0.3.0) 于 2021-02-16 创建

在上面的代码中,我必须两次指定相同的条件,每个新列一个。

  • IF mpg &lt;= 17 &amp; am == 0 THEN 赋值 X
  • IF mpg &gt; 17 &amp; am == 1 THEN 赋值 Y

我是否可以使用这组条件来改变几个新列,以便每列都有自己的 X 和 Y 值?


在我的实际数据中,我经常遇到复杂的条件,这些条件会导致许多新列发生变异,而且我发现自己一遍又一遍地重复相同的代码来处理条件。有没有办法将条件勾勒一次,然后根据同一组条件创建多个列?


编辑 1


我想知道——尽管它不会完全解决上述问题——是否有办法将条件存储到对象中并在以后解包?比如:

cond_1 <- {mpg <= 17 & am == 0}
cond_2 <- {mpg > 17 & am == 1}

mtcars %>%
  select(mpg, am) %>%
  mutate(economic = case_when(cond_1  ~ "no",
                              cond_2  ~ "yes"),

         label = case_when(cond_1  ~ "red",
                           cond_2  ~ "green"))

至少会让代码更简洁...


编辑 2


基于this solution,我学会了如何回答我在EDIT 1中提出的问题:

library(dplyr)
library(rlang)

cond_1 <- parse_expr("mpg <= 17 & am == 0")
cond_2 <- parse_expr("mpg > 17 & am == 1")

mtcars %>%
  select(mpg, am) %>%
  mutate(economic = case_when(!!cond_1  ~ "no",
                              !!cond_2  ~ "yes"),
         
         label = case_when(!!cond_1  ~ "red",
                           !!cond_2  ~ "green"))

#>                      mpg am economic label
#> Mazda RX4           21.0  1      yes green
#> Mazda RX4 Wag       21.0  1      yes green
#> Datsun 710          22.8  1      yes green
#> Hornet 4 Drive      21.4  0     <NA>  <NA>
#> Hornet Sportabout   18.7  0     <NA>  <NA>
#> Valiant             18.1  0     <NA>  <NA>
#> Duster 360          14.3  0       no   red
#> Merc 240D           24.4  0     <NA>  <NA>
#> Merc 230            22.8  0     <NA>  <NA>
#> Merc 280            19.2  0     <NA>  <NA>
#> Merc 280C           17.8  0     <NA>  <NA>
#> Merc 450SE          16.4  0       no   red
#> Merc 450SL          17.3  0     <NA>  <NA>
#> Merc 450SLC         15.2  0       no   red
#> Cadillac Fleetwood  10.4  0       no   red
#> Lincoln Continental 10.4  0       no   red
#> Chrysler Imperial   14.7  0       no   red
#> Fiat 128            32.4  1      yes green
#> Honda Civic         30.4  1      yes green
#> Toyota Corolla      33.9  1      yes green
#> Toyota Corona       21.5  0     <NA>  <NA>
#> Dodge Challenger    15.5  0       no   red
#> AMC Javelin         15.2  0       no   red
#> Camaro Z28          13.3  0       no   red
#> Pontiac Firebird    19.2  0     <NA>  <NA>
#> Fiat X1-9           27.3  1      yes green
#> Porsche 914-2       26.0  1      yes green
#> Lotus Europa        30.4  1      yes green
#> Ford Pantera L      15.8  1     <NA>  <NA>
#> Ferrari Dino        19.7  1      yes green
#> Maserati Bora       15.0  1     <NA>  <NA>
#> Volvo 142E          21.4  1      yes green

reprex package (v0.3.0) 于 2021 年 2 月 16 日创建

但是,这只会使代码更易于阅读。但是这篇文章的主要问题——条件句的重复——仍然存在。

【问题讨论】:

  • 那么在这个修改后的场景中,你的问题到底是什么?
  • 我需要多次重复相同的条件。这是一个玩具示例,但想象一下这样一种情况:不仅要创建 economiclabel 列,而且还有 10 个基于同一组条件的新列。我不想重复代码 10 次。

标签: r dplyr


【解决方案1】:

并不是真正的最佳解决方案,但一种方法是使用以前创建的列作为输入来创建新列。这样可以避免一次又一次地编写条件。

library(dplyr)

mtcars %>%
  select(mpg, am) %>%
  mutate(economic = case_when(mpg <= 17 & am == 0 ~ "no",
                              mpg > 17 & am == 1 ~ "yes"),
         label = recode(economic, "no" = "red", "yes" = "green"))

【讨论】:

  • 是的,它会工作,但我认为这样的代码会令人困惑。
猜你喜欢
  • 2019-10-21
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 2020-09-12
相关资源
最近更新 更多