我有一个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,但我认为存在范围问题。
你们是最好的。谢谢!
答案 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循环工作,但速度非常慢。看起来这些其他解决方案的工作速度更快!