Кодировать числа в категориальные векторы - PullRequest
0 голосов
/ 23 октября 2018

У меня есть вектор целых чисел 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

Ответы [ 4 ]

0 голосов
/ 27 октября 2018

Еще одна опция предоставляет пакет 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
0 голосов
/ 23 октября 2018

Я предпочитаю ответ @ akrun для простоты, но некоторые альтернативы:

Данные:

dat <- data.frame(y=c(1,2,3,3))
dat$id <- seq_len(nrow(dat))
dat$one <- 1L

С добавленным полем "id" для сохранения отдельных / уникальных строк.Поскольку я меняю данные, мне нужно сохранить значение, поэтому временная переменная "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
0 голосов
/ 27 октября 2018

Однострочник с 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
0 голосов
/ 23 октября 2018

Вот один из способов base R.Создайте matrix из 0 и присвойте 1 на основе последовательности строк и значения y в качестве индекса столбца

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...