单热编码 R 字符列表

One-hot-encoding a R list of characters

我有以下 R 数据框:

id    color
001   blue
001   yellow
001   red
002   blue
003   blue
003   yellow

将这样的数据帧单热编码为以下内容的一般方法是什么:

id    blue    yellow    red
001   1       1         1
002   1       0         0
003   1       0         1

非常感谢。

试试这个。您可以为数据中存在的那些观察结果创建一个等于 1 的变量,然后使用 pivot_wider() 重塑值。由于数据中不存在 类,您将得到 NA,因此您可以使用 replace() 将其替换为零。这里的代码使用 tidyverse 函数:

library(dplyr)
library(tidyr)
#Code
dfnew <- df %>% mutate(val=1) %>%
  pivot_wider(names_from = color,values_from=val) %>%
  replace(is.na(.),0)

输出:

# A tibble: 3 x 4
     id  blue yellow   red
  <int> <dbl>  <dbl> <dbl>
1     1     1      1     1
2     2     1      0     0
3     3     1      1     0

使用了一些数据:

#Data
df <- structure(list(id = c(1L, 1L, 1L, 2L, 3L, 3L), color = c("blue", 
"yellow", "red", "blue", "blue", "yellow")), class = "data.frame", row.names = c(NA,-6L))

data.table:

library(data.table)
dcast(setDT(df), id ~ color, fun.aggregate = length)

#     id blue red yellow
# 1: 001    1   1      1
# 2: 002    1   0      0
# 3: 003    1   0      1

tidyr相同的逻辑:

library(tidyr)
pivot_wider(df, names_from=color, values_from=color, values_fn=length, values_fill=0)

#   id     blue yellow   red
#   <chr> <int>  <int> <int>
# 1 001       1      1     1
# 2 002       1      0     0
# 3 003       1      1     0

Base R:

out <- as.data.frame.matrix(pmin(with(df, table(id, color)), 1))
out$id <- rownames(out)
out
#     blue red yellow  id
# 001    1   1      1 001
# 002    1   0      0 002
# 003    1   0      1 003

可重现的数据

df <- data.frame(
  id = c("001", "001", "001", "002", "003", "003"), 
  color = c("blue", "yellow", "red", "blue", "blue", "yellow")
)

在 R 中有很多方法可以做到这一点。这取决于您使用的是什么包。大多数建模包,例如 carettidymodels 都具有为您执行此操作的功能。

但是,如果您不使用建模包,tidyverse 有一个简单的方法可以做到这一点。

library(dplyr)
library(tidyr)

df <- tribble(
  ~id,    ~color,
  '001',   'blue',
  '001',   'yellow',
  '001',   'red',
  '002',   'blue',
  '003',   'blue',
  '003',   'yellow')

df_onehot <- df %>%
  mutate(value = 1) %>%
  pivot_wider(names_from = color,values_from = value,values_fill = 0)
# A tibble: 3 x 4
#    id     blue yellow   red
#   <chr> <dbl>  <dbl> <dbl>
# 1 001       1      1     1
# 2 002       1      0     0
# 3 003       1      1     0