R dplyr создать несколько столбцов эффективно с условием - PullRequest
1 голос
/ 20 февраля 2020

Допустим, у меня есть этот тиббл:

 tb <- tribble(
  ~siren_ent, ~region_etab,
  "a",   "11",
  "b",   "32",
  "c",   "76"
)

, и я хотел бы добавить 3 новых столбца, например:

result <- tribble(
  ~siren_ent, ~region_etab, ~reg11, ~reg21, ~reg76,
  "a",   "11", 1,0,0,
  "b",   "32", 0,1,0,
  "c",   "76", 0,0,1
)

Он работает с этими строками, но не работает с много столбцов ...

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)
  )

Любой совет, чтобы сделать это с dplyr и, возможно, функция (х)? Большое спасибо!

Ответы [ 3 ]

2 голосов
/ 20 февраля 2020
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
1 голос
/ 20 февраля 2020

Я думаю, что это можно сделать более эффективно с pivot_wider, который заменяет 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

Создан в 2020-02-20 с помощью представ пакет (v0.3.0)

0 голосов
/ 20 февраля 2020

Это, вероятно, не очень хорошо работает с большими фреймами данных ...

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"))
...