如何在 R 中一次性编码堆叠列

How to One-Hot Encoding stacked columns in R

我有这样的数据

+---+-------+
|   |  col1 |
+---+-------+
| 1 |     A |
| 2 |   A,B |
| 3 |   B,C |
| 4 |     B |
| 5 | A,B,C |
+---+-------+

预期输出

+---+-----------+
|   | A | B | C |
+---+-----------+
|1  | 1 | 0 | 0 |
|2  | 1 | 1 | 0 |
|3  | 0 | 1 | 1 |
|4  | 0 | 1 | 0 |
|5  | 1 | 1 | 1 |
+---+---+---+---+

如何编码成这样?

也许这会有所帮助

df %>%
  mutate(r = 1:n()) %>%
  unnest(col1) %>%
  table() %>%
  t()

这给出了

   col1
r   A B C
  1 1 0 0
  2 1 1 0
  3 0 1 1
  4 0 1 0
  5 1 1 1

数据

df <- tibble(
  col1 = list(
    "A",
    c("A", "B"),
    c("B", "C"),
    "B",
    c("A", "B", "C")
  )
)

如果您的数据按以下格式给出

df <- data.frame(
  col1 = c("A", "A,B", "B,C", "B", "A,B,C")
)

那你可以试试

with(
  df,
  table(rev(stack(setNames(strsplit(col1, ","), seq_along(col1)))))
)

这给出了

   values
ind A B C
  1 1 0 0
  2 1 1 0
  3 0 1 1
  4 0 1 0
  5 1 1 1

您可以使用 table() 和来自 purrr 的 map_df() 来计算出现次数 在列表的每个元素中,以及 return 数据框。把它放进一个 具有一些 post 处理功能,并使用 dplyrs 数据帧解包 mutate(),您可以这样做以保持在数据框中 上下文:

library(tidyverse)

one_hot <- function(x) {
  map_df(x, table) %>% 
    mutate_all(as.integer) %>% 
    mutate_all(replace_na, 0L)
}

df <- data.frame(col1 = c("A", "A,B", "B,C", "B", "A,B,C"))

df %>% 
  mutate(
    one_hot(strsplit(col1, ","))
  )
#>    col1 A B C
#> 1     A 1 0 0
#> 2   A,B 1 1 0
#> 3   B,C 0 1 1
#> 4     B 0 1 0
#> 5 A,B,C 1 1 1

一个额外的基础 R 解决方案:

+(
  with(
    df, 
    sapply(
      unique(
        unlist(
          strsplit(
            col1, 
            ","
            )
          )
        ),
      `grepl`, 
      col1
    )
  )
)