Damien Dotta
Damien Dotta

Reputation: 939

R dplyr create multiple columns efficiently with condition

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

Answers (3)

Giovanni Colitti
Giovanni Colitti

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

EJJ
EJJ

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

eipi10
eipi10

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

Related Questions