如何创建每行库存的二进制矩阵? (R)

时间:2012-01-24 03:30:09

标签: r sparse-matrix cluster-analysis

我有一个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-clustering(这是我想做的事情,但我需要首先摆脱NAs),模糊聚类,标签聚类。只是有点迷失方向。

我尝试编写两个for循环,通过列/行从矩阵中提取数据,然后分别在新矩阵中保存0和1,但我认为存在范围问题。

你们是最好的。谢谢!

3 个答案:

答案 0 :(得分:5)

这是基础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

答案 1 :(得分:3)

这应该可以解决问题:

# 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

答案 2 :(得分:1)

这些都是很好的答案。以为我会贡献我写的一个原始解决方案,我的一个朋友修改了实际工作。

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循环工作,但速度非常慢。看起来这些其他解决方案的工作速度更快!