【问题标题】:Recode levels of multiple factors to specified range将多个因子的水平重新编码到指定范围
【发布时间】:2020-10-20 14:58:25
【问题描述】:

我有以下数据框:

library(tidyverse)
df <- tibble(a = c(1, 2, 3, 4, 5),
             b = c("Y", "N", "N", "Y", "N"),
             c = c("A", "B", "C", "A", "B"))

df <- df %>%
  mutate_if(is.character, funs(as.factor))

df的输出:

      a b     c    
  <dbl> <fct> <fct>
1     1 Y     A    
2     2 N     B    
3     3 N     C    
4     4 Y     A    
5     5 N     B    

我想将所有因子(bc 变量)级别重新编码为整数:如果一个因子只有两个级别,则应将其重新编码为 {0, 1},否则为 {1, 2, 3 , ...} 级。所以输出应该是:

      a b     c    
  <dbl> <fct> <fct>
1     1 1     1    
2     2 0     2    
3     3 0     3    
4     4 1     1    
5     5 0     2    

我可以单独(一个一个)重新编码变量,但我想知道是否有更方便的方法。

【问题讨论】:

    标签: r dplyr forcats


    【解决方案1】:
    df <- df %>%
      mutate_if(
        is.character,
        function(x) {
          out <- as.integer(as.factor(x))
          if (n_distinct(out) == 2) out <- out - 1L
          out
        }
      )
    df
    
    #       a     b     c
    #   <dbl> <int> <int>
    # 1     1     1     1
    # 2     2     0     2
    # 3     3     0     3
    # 4     4     1     1
    # 5     5     0     2
    

    【讨论】:

      【解决方案2】:

      一个dplyr 选项可能是:

      df %>%
       mutate(across(where(is.factor), 
                     ~ if(n_distinct(.) == 2) factor(., labels = 0:1) else factor(., labels = 1:n_distinct(.))))
      
            a b     c    
        <dbl> <fct> <fct>
      1     1 1     1    
      2     2 0     2    
      3     3 0     3    
      4     4 1     1    
      5     5 0     2
      

      【讨论】:

        【解决方案3】:

        这行得通吗:

        > library(dplyr)
        > df %>% mutate(b_fac = match(b,unique(b)) - 1, c_fac = match(c, unique(c))) %>% 
        +       mutate(b_fac = ifelse(b_fac == 1, 0, 1)) %>% mutate(b_fac = as.factor(b_fac), c_fac = as.factor(c_fac))  %>% 
        +       select(-2,-3) %>% rename(b = b_fac, c = c_fac)
        # A tibble: 5 x 3
              a b     c    
          <dbl> <fct> <fct>
        1     1 1     1    
        2     2 0     2    
        3     3 0     3    
        4     4 1     1    
        5     5 0     2    
        > 
        

        【讨论】:

          猜你喜欢
          • 2021-03-02
          • 1970-01-01
          • 2016-12-24
          • 2017-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多