基于以某个字符开头的级别的自动重构?

时间:2019-05-31 15:28:13

标签: r refactoring categorical-data forcats

我正在寻找一种根据级别中的某些模式自动重新编码变量中的因子的方法。我打算迭代解决方案以处理更大的数据集。

我有一个较大的数据集,其中包含下面显示的示例的多个实例。这些级别通常具有以下模式:

主要类别为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

reprex package(v0.2.1)于2019-05-31创建

此方法成功地将11、12、13和14的子类别分组为1。有没有一种方法可以手动更改每个子类别的级别?将这个过程扩展到具有相同模式的多个变量的通用方法是什么?谢谢。

2 个答案:

答案 0 :(得分:1)

一个选项是创建一个命名向量并求值(collectstatic

!!!

或者另一种选择是根据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

对于多列,请使用levels(dat$Ethnicity)[substr(levels(dat$Ethnicity), 1, 1) == 1] <- 1 dat %>% count(Ethnicity) 并指定感兴趣的变量

mutate_at

答案 1 :(得分:1)

您可以将fct_collapsegrep /正则表达式结合使用,并根据需要调整正则表达式模式:

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

或者,这有点hacker,但是您可以始终使用ifelsecase_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