将数字编码为分类向量
Encode numbers into categorical vectors
我有一个整数向量 y <- c(1, 2, 3, 3)
,现在我想将它转换成这样的列表(一个热编码):
1 0 0
0 1 0
0 0 1
0 0 1
我试图找到 to_categorical 的解决方案,但我遇到了数据类型的问题...有谁知道这个任务的智能和流畅的解决方案?
这是我的尝试:
for (i in 1:length(y)) {
one_character <- list(as.vector(to_categorical(y[[i]], num_classes = 3)))
list_test <- rbind(list_test, one_character)
}
但我收到以下错误:
Error in py_call_impl(callable, dots$args, dots$keywords) :
IndexError: index 3 is out of bounds for axis 1 with size 3
这是 base R
中的一种方法。创建一个 matrix
的 0s 并根据行的顺序和 y 值分配 1 作为列索引
m1 <- matrix(0, length(y), max(y))
m1[cbind(seq_along(y), y)] <- 1
m1
# [,1] [,2] [,3]
#[1,] 1 0 0
#[2,] 0 1 0
#[3,] 0 0 1
#[4,] 0 0 1
在base R
中,我们也可以做到
table(seq_along(y), y)
# y
# 1 2 3
# 1 1 0 0
# 2 0 1 0
# 3 0 0 1
# 4 0 0 1
或者另一个选项是 model.frame
来自 base R
model.matrix(~factor(y) - 1)
为简单起见,我更喜欢@akrun 的回答,但也有其他选择:
数据:
dat <- data.frame(y=c(1,2,3,3))
dat$id <- seq_len(nrow(dat))
dat$one <- 1L
添加了 "id" 字段以保留行 separate/unique。由于我正在重塑数据,我需要保留一个值,因此临时变量 "one".
基本R
dat_base <- reshape(dat, idvar="id", v.names="one", timevar="y", direction="wide")
dat_base[2:4] <- lapply(dat_base[2:4], function(a) replace(a, is.na(a), 0))
dat_base
# id one.1 one.2 one.3
# 1 1 1 0 0
# 2 2 0 1 0
# 3 3 0 0 1
# 4 4 0 0 1
dplyr
library(dplyr)
library(tidyr)
dat %>%
spread(y, one) %>%
mutate_all(~if_else(is.na(.), 0L, .))
# id 1 2 3
# 1 1 1 0 0
# 2 2 0 1 0
# 3 3 0 0 1
# 4 4 0 0 1
data.table
library(data.table)
datdt <- as.data.table(dat)
dcast(datdt, id ~ y, value.var = "one", fill = 0)
# id 1 2 3
# 1: 1 1 0 0
# 2: 2 0 1 0
# 3: 3 0 0 1
# 4: 4 0 0 1
带有 mltools
和 data.table
的一行:
one_hot(as.data.table(as.factor(y)))
V1_1 V1_2 V1_3
1: 1 0 0
2: 0 1 0
3: 0 0 1
4: 0 0 1
另一个选项提供了 splitstackshape
包。
y <- c(1, 2, 3, 3)
splitstackshape:::numMat(y, fill = 0L)
# 1 2 3
#[1,] 1 0 0
#[2,] 0 1 0
#[3,] 0 0 1
#[4,] 0 0 1
我有一个整数向量 y <- c(1, 2, 3, 3)
,现在我想将它转换成这样的列表(一个热编码):
1 0 0
0 1 0
0 0 1
0 0 1
我试图找到 to_categorical 的解决方案,但我遇到了数据类型的问题...有谁知道这个任务的智能和流畅的解决方案?
这是我的尝试:
for (i in 1:length(y)) {
one_character <- list(as.vector(to_categorical(y[[i]], num_classes = 3)))
list_test <- rbind(list_test, one_character)
}
但我收到以下错误:
Error in py_call_impl(callable, dots$args, dots$keywords) :
IndexError: index 3 is out of bounds for axis 1 with size 3
这是 base R
中的一种方法。创建一个 matrix
的 0s 并根据行的顺序和 y 值分配 1 作为列索引
m1 <- matrix(0, length(y), max(y))
m1[cbind(seq_along(y), y)] <- 1
m1
# [,1] [,2] [,3]
#[1,] 1 0 0
#[2,] 0 1 0
#[3,] 0 0 1
#[4,] 0 0 1
在base R
中,我们也可以做到
table(seq_along(y), y)
# y
# 1 2 3
# 1 1 0 0
# 2 0 1 0
# 3 0 0 1
# 4 0 0 1
或者另一个选项是 model.frame
来自 base R
model.matrix(~factor(y) - 1)
为简单起见,我更喜欢@akrun 的回答,但也有其他选择:
数据:
dat <- data.frame(y=c(1,2,3,3))
dat$id <- seq_len(nrow(dat))
dat$one <- 1L
添加了 "id" 字段以保留行 separate/unique。由于我正在重塑数据,我需要保留一个值,因此临时变量 "one".
基本R
dat_base <- reshape(dat, idvar="id", v.names="one", timevar="y", direction="wide")
dat_base[2:4] <- lapply(dat_base[2:4], function(a) replace(a, is.na(a), 0))
dat_base
# id one.1 one.2 one.3
# 1 1 1 0 0
# 2 2 0 1 0
# 3 3 0 0 1
# 4 4 0 0 1
dplyr
library(dplyr)
library(tidyr)
dat %>%
spread(y, one) %>%
mutate_all(~if_else(is.na(.), 0L, .))
# id 1 2 3
# 1 1 1 0 0
# 2 2 0 1 0
# 3 3 0 0 1
# 4 4 0 0 1
data.table
library(data.table)
datdt <- as.data.table(dat)
dcast(datdt, id ~ y, value.var = "one", fill = 0)
# id 1 2 3
# 1: 1 1 0 0
# 2: 2 0 1 0
# 3: 3 0 0 1
# 4: 4 0 0 1
带有 mltools
和 data.table
的一行:
one_hot(as.data.table(as.factor(y)))
V1_1 V1_2 V1_3
1: 1 0 0
2: 0 1 0
3: 0 0 1
4: 0 0 1
另一个选项提供了 splitstackshape
包。
y <- c(1, 2, 3, 3)
splitstackshape:::numMat(y, fill = 0L)
# 1 2 3
#[1,] 1 0 0
#[2,] 0 1 0
#[3,] 0 0 1
#[4,] 0 0 1