Как создать бинарную матрицу инвентаря на строку?(Р) - PullRequest
6 голосов
/ 24 января 2012

У меня есть датафрейм из 9 столбцов, состоящий из перечня факторов. В каждой строке могут быть заполнены все 9 столбцов (так как в этой строке содержится 9 «вещей»), но большинство не имеют (большинство из них имеют 3-4). Столбцы также не являются конкретными, как в случае, если элемент 200 появляется в столбцах 1 и 3, это то же самое. Я хотел бы создать матрицу, которая является двоичной для каждой строки, которая включает все факторы.

Ex (сокращено до 4 столбцов только для того, чтобы получить точку)

R1 3  4   5   8
R2 4  6   7   NA
R3 1  5  NA   NA
R4 2  6   8   9

должно превратиться в

     1  2  3  4  5  6  7  8  9 
r1   0  0  1  1  1  0  0  1  0
r2   0  0  0  1  0  1  1  0  0
r3   1  0  0  0  1  0  0  0  0
r4   0  1  0  0  0  1  0  1  1

Я смотрел на writeBin / readBin, K-кластеризацию (это то, что я хотел бы сделать, но сначала мне нужно избавиться от NA), нечеткая кластеризация, кластеризация тегов. Просто немного не знаю, в каком направлении идти.

Я пытался написать два цикла for, которые извлекают данные из матрицы по столбцу / строке, а затем сохраняют 0 и 1 соответственно в новой матрице, но я думаю, что были проблемы с областью действия.

Вы, ребята, лучшие. Спасибо!

Ответы [ 3 ]

5 голосов
/ 24 января 2012

Вот базовое решение R:

# Read in the data, and convert to matrix form
df <- read.table(text = "
3  4   5   8
4  6   7   NA
1  5  NA   NA
2  6   8   9", header = FALSE)
m <- as.matrix(df)

# Create a two column matrix containing row/column indices of cells to be filled 
# with 'one's
id <- cbind(rowid = as.vector(t(row(m))), 
            colid = as.vector(t(m)))
id <- id[complete.cases(id), ]

# Create output matrix
out <-  matrix(0, nrow = nrow(m), ncol = max(m, na.rm = TRUE))
out[id] <- 1
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,]    0    0    1    1    1    0    0    1    0
# [2,]    0    0    0    1    0    1    1    0    0
# [3,]    1    0    0    0    1    0    0    0    0
# [4,]    0    1    0    0    0    1    0    1    1
3 голосов
/ 24 января 2012

Это должно сработать:

# The Incantation
options(stringsAsFactors = FALSE)

library(reshape2)

# Your example data
dat <- data.frame(id = c("R1", "R2", "R3", "R4"),
                  col1 = c(3, 4, 1, 2),
                  col2 = c(4, 6, 5, 6),
                  col3 = c(5, 7, NA, 7),
                  col4 = c(8, NA, NA, 9)
)

# Melt it down
dat.melt <- melt(dat, id.var = "id")

# Cast it back out, with the row IDs remaining the row IDs
# and the values of the columns becoming the columns themselves.
# dcast() will default to length to aggregate records - which means
# that the values in this data.frame are a count of how many times
# each value occurs in each row's columns (which, based on this data,
# seems to be capped at just once).
dat.cast <- dcast(dat.melt, id ~ value)

Результат:

dat.cast
  id 1 2 3 4 5 6 7 8 9 NA
1 R1 0 0 1 1 1 0 0 1 0  0
2 R2 0 0 0 1 0 1 1 0 0  1
3 R3 1 0 0 0 1 0 0 0 0  2
4 R4 0 1 0 0 0 1 1 0 1  0
1 голос
/ 24 января 2012

Это все отличные ответы.Думая, что я внесу оригинальное решение, которое я написал, мой друг изменился, чтобы фактически работать.

for(i in seq(nrow(x)))
  for(j in seq(ncol(x)))
  if(!is.na(x[i,j])) { y[i, x[i,j]] = 1 }

Два цикла for работают после установки некоторых более ранних параметров, но это невероятно медленно.Похоже, эти другие решения работают намного быстрее!

...