当我们想根据一个条件改变几个新列时,有没有办法避免重复代码?
例如,在 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 年 2 月 16 日创建
在上面的代码中,我必须两次指定相同的条件,每个新列一个。
mpg <= 17 & am == 0
THEN 赋值 Xmpg > 17 & 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,我学会了如何回答我在编辑 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 日创建
然而,这只会使代码更易于阅读。但是这篇文章的主要问题——条件的重复——仍然存在。
答案 0 :(得分:0)
并不是真正的最佳解决方案,但一种方法是使用先前创建的列作为输入来创建新列。这样可以避免一次又一次地编写条件。
=1=INDIRECT("Sheet1!"&CELL("address",A1))