Автоматический рефакторинг на основе уровней, начинающихся с определенного персонажа? - PullRequest
2 голосов
/ 31 мая 2019

Я ищу метод для автоматического перекодирования факторов внутри переменной на основе некоторого паттерна уровней.Я намерен повторить решение для большего набора данных.

У меня есть большой набор данных, который имеет несколько экземпляров примера, который я показываю ниже.Уровни, как правило, имеют следующую структуру:

Основными категориями являются 1, 2, 3 и 4. Уровни 11, 12, 13 и 14 являются подкатегориями уровня 1. Я хочу иметь возможность упорядочитьпроцесс группировки.Я успешно выполнил рефакторинг, используя fct_recode, но я намерен распространить эту процедуру на другие переменные, которые следуют аналогичному шаблону кодирования.

library(tidyverse)

dat <- tribble(
  ~Ethnicity, 
  "1",
  "2",
  "3",
  "4",
  "11",
  "12",
  "13",
  "14",
  "11",
  "13",
  "12",
  "12",
  "11",
  "13")

dat <- mutate_at(dat, vars(Ethnicity), factor)

count(dat, Ethnicity)
#> # A tibble: 8 x 2
#>   Ethnicity     n
#>   <fct>     <int>
#> 1 1             1
#> 2 11            3
#> 3 12            3
#> 4 13            3
#> 5 14            1
#> 6 2             1
#> 7 3             1
#> 8 4             1

dat %>% 
  mutate(Ethnicity = fct_recode(Ethnicity,
                                "1" = "1",
                                "1" = "11",
                                "1" = "12",
                                "1" = "13",
                                "1" = "14"
                                )) %>% 
  count(Ethnicity)
#> # A tibble: 4 x 2
#>   Ethnicity     n
#>   <fct>     <int>
#> 1 1            11
#> 2 2             1
#> 3 3             1
#> 4 4             1

Создано в 2019-05-31 пользователем представьте пакет (v0.2.1)

Этот метод успешно группирует подкатегории 11, 12, 13 и 14 в 1, как и ожидалось.Есть ли способ сделать это без изменения уровней вручную для каждой подкатегории?И каков будет общий метод расширения этого процесса на несколько переменных, имеющих одинаковую структуру?Спасибо.

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Вы можете использовать fct_collapse с grep / regex и корректировать шаблон регулярных выражений по мере необходимости:

dat %>%
  mutate(Ethnicity = fct_collapse(Ethnicity, 
                                  "1" = unique(grep("^1", Ethnicity, value = T)))) %>%
  count(Ethnicity)

# A tibble: 4 x 2
  Ethnicity     n
  <fct>     <int>
1 1            11
2 2             1
3 3             1
4 4             1

Или это кажется немного хакерским, но вы всегда можете использовать ifelse или case_when:

dat %>%
  mutate(Ethnicity = factor(ifelse(startsWith(as.character(Ethnicity), "1"), 1, Ethnicity))) %>%
  count(Ethnicity)

# A tibble: 4 x 2
  Ethnicity     n
  <fct>     <int>
1 1            11
2 2             1
3 3             1
4 4             1
1 голос
/ 31 мая 2019

Можно создать именованный вектор и оценить (!!!)

library(dplyr)
library(forcats)
lvls <- levels(dat$Ethnicity)[substr(levels(dat$Ethnicity), 1, 1) == 1]
nm1 <- setNames(lvls, rep(1, length(lvls)))
dat %>% 
     mutate(Ethnicity = fct_recode(Ethnicity, !!!nm1)) %>% 
     count(Ethnicity)
# A tibble: 4 x 2
#  Ethnicity     n
#  <fct>     <int>
#1 1            11
#2 2             1
#3 3             1
#4 4             1

Или другой вариант - установить levels на основе substr ing

levels(dat$Ethnicity)[substr(levels(dat$Ethnicity), 1, 1) == 1] <- 1
dat %>% 
   count(Ethnicity)

Для нескольких столбцов используйте mutate_at и укажите интересующие переменные

dat %>% 
    mutate_at(vars(colsOfInterst), list(~ fct_recode(., !!! nm1)))
...