Reputation: 939
Let's say I have this tibble :
tb <- tribble(
~siren_ent, ~region_etab,
"a", "11",
"b", "32",
"c", "76"
)
and I would like to add 3 new columns like this :
result <- tribble(
~siren_ent, ~region_etab, ~reg11, ~reg21, ~reg76,
"a", "11", 1,0,0,
"b", "32", 0,1,0,
"c", "76", 0,0,1
)
It works with that lines but it's not effective with a lot of colums...
tb %>%
mutate(
reg11=if_else(region_etab=="11",1,0),
reg32=if_else(region_etab=="32",1,0),
reg76=if_else(region_etab=="76",1,0)
)
Any advice to do it with dplyr and maybe a function(x) ? Many thanks !
Upvotes: 1
Views: 208
Reputation: 2344
I think this can be done more efficiently with pivot_wider
, which is set to replace spread
.
library(dplyr)
library(tidyr)
tb <- tribble(
~siren_ent, ~region_etab,
"a", "11",
"b", "32",
"c", "76"
)
tb %>%
mutate(val = 1,
region_etab_tmp = region_etab) %>%
pivot_wider(
names_from = region_etab_tmp,
values_from = val,
names_prefix = "reg",
values_fill = list(val = 0)
)
#> # A tibble: 3 x 5
#> siren_ent region_etab reg11 reg32 reg76
#> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 a 11 1 0 0
#> 2 b 32 0 1 0
#> 3 c 76 0 0 1
Created on 2020-02-20 by the reprex package (v0.3.0)
Upvotes: 1
Reputation: 1513
This probably doesn't work well with large data frames...
library(dplyr)
library(purrr)
my_mutate <- function(x, condition) {
mutate(x, !!paste0("reg", condition) := ifelse(region_etab == condition, 1, 0))
}
map(c(11,32,76), ~my_mutate(tb, .)) %>%
purrr::reduce(inner_join, by = c("siren_ent", "region_etab"))
Upvotes: 0
Reputation: 93871
library(tidyverse)
tb %>%
mutate(reg.tmp = paste0("reg", region_etab),
x=1) %>%
spread(reg.tmp, x, fill=0)
siren_ent region_etab reg11 reg32 reg76 1 a 11 1 0 0 2 b 32 0 1 0 3 c 76 0 0 1
Upvotes: 2