用包括 NAs 在内的许多值重新编码一个数字变量

Recode a numeric variable with many values including NAs

如何以整洁的方式重新编码包含多个值(包括缺失值)的数值变量,使其具有数字 0:n-1,其中 n 是包括 NA 在内的唯一值的数量?

示例:

df <- tibble(x = c(1000, 1000, NA, 1001, 1002, 1003, NA, 1003))

所需输出(尽管它可以是任何重新编码方案,只要值为 0:n-1):

# A tibble: 8 x 2
      x     y
  <dbl> <dbl>
1  1000     0
2  1000     0
3    NA     4
4  1001     1
5  1002     2
6  1003     3
7    NA     4
8  1003     3

am 能够通过首先将 x 转换为一个因子然后使用 fct_recode() 和命名列表(自动创建因为请记住 x 中有 很多 个值),然后返回数字:

df <- df %>% mutate(x_fct = factor(case_when(
    is.na(x) ~ "level_na",
    TRUE ~ str_c("level_", x)
  )))
x_levels <- levels(df$x_fct)
n_levels <- length(x_levels)
names(x_levels) <- as.character(0:(n_levels - 1))
df <- df %>%
  mutate(y = as.numeric(fct_recode(x_fct, !!!x_levels)) - 1)
df
# A tibble: 8 x 3
      x x_fct          y
  <dbl> <fct>      <dbl>
1  1000 level_1000     0
2  1000 level_1000     0
3    NA level_na       4
4  1001 level_1001     1
5  1002 level_1002     2
6  1003 level_1003     3
7    NA level_na       4
8  1003 level_1003     3

但这看起来很麻烦。当然有更简单的方法,最好是在单个管道中。

一种方法是使用 match + unique。可以加sample来增加随机性

library(dplyr)

df %>%
  mutate(level = paste('level', x, sep = '_'), 
         y = match(x, sample(unique(x))) - 1)

#      x level          y
#  <dbl> <chr>      <dbl>
#1  1000 level_1000     4
#2  1000 level_1000     4
#3    NA level_NA       2
#4  1001 level_1001     0
#5  1002 level_1002     1
#6  1003 level_1003     3
#7    NA level_NA       2
#8  1003 level_1003     3