Как создать бинарную матрицу запасов в строке? (Р)
у меня есть фрейм данных из 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-кластеризацию (что я хотел бы сделать, но сначала мне нужно избавиться от NAs), нечеткую кластеризацию, кластеризацию тегов. Просто не знаю, в каком направлении идти.
Я попытался написать два цикла, которые вытягивают данные из Матрицы по столбцу / строке, а затем сохраняют 0 и 1 соответственно в новой матрице, но я думаю, что были проблемы с областью.
Вы самые лучшие. Спасибо!
3 ответов
вот базовое решение 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
Это должно сделать трюк:
# 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
Это все отличные ответы. Думал, что я внесу оригинальное решение, которое я написал, что мой друг модифицирован, чтобы действительно работать.
for(i in seq(nrow(x)))
for(j in seq(ncol(x)))
if(!is.na(x[i,j])) { y[i, x[i,j]] = 1 }
два для циклов работает после установки некоторых более ранних параметров, но это невероятно медленно. Похоже, другие решения работают намного быстрее!