Advertisements
I have a data frame containing numbers that I would like to bin according to their absolute value.
library(tidyverse)
dat <- data.frame(val = seq(-10, 10))
The following command accomplishes what I would like to do, but the values are hardcoded which I need to avoid:
dat %>%
mutate(grp = case_when(abs(val) <= 5 ~ "Grp 1",
abs(val) <= 7 ~ "Grp 2",
TRUE ~ "Grp 3"))
How can I accomplish the same transformation, but instead using a named vector as the input:
grps <- c("Grp 1" = 5, "Grp 2" = 7)
So that I can add/remove groups as needed, for example, adding in "Grp 3" = 9
?
>Solution :
Instead of using map
or something that works one-by-one, we can do it vectorized with cut
:
grps <- c("Grp 1" = 5, "Grp 2" = 7)
dat %>%
mutate(
grp = cut(abs(val), c(-Inf, grps, Inf), labels = c(names(grps), "Grp 3"))
)
# val grp
# 1 -10 Grp 3
# 2 -9 Grp 3
# 3 -8 Grp 3
# 4 -7 Grp 2
# 5 -6 Grp 2
# 6 -5 Grp 1
# 7 -4 Grp 1
# 8 -3 Grp 1
# 9 -2 Grp 1
# 10 -1 Grp 1
# 11 0 Grp 1
# 12 1 Grp 1
# 13 2 Grp 1
# 14 3 Grp 1
# 15 4 Grp 1
# 16 5 Grp 1
# 17 6 Grp 2
# 18 7 Grp 2
# 19 8 Grp 3
# 20 9 Grp 3
# 21 10 Grp 3
Note that grp
is a factor
; if you want it to be character
, just wrap it in as.character
.