使用值标志生成矩阵

时间:2012-07-10 00:16:31

标签: r

我确实有针对以下问题的解决方案,但它非常难看,而且很可能以更短的方式完成。很高兴得到你的帮助。

我的输入如下:

C1     C2 
A      B     
B      D    
D      C 
A      D

我的输出应该如下所示:

A B C D
1 1 0 0
0 1 0 1
0 0 1 1  
1 0 0 1

我目前的解决方案是:

index <- unique(unlist(input[,1:2]))
output <- matrix(0,nrows=dim(input),ncols=length(index))
for(i in 1:dim(input)) {
    output[i, input[i,]$C1] <- 1
    output[i, input[i,]$C2] <- 1
}

当然4-5行实际上很好 - 但即使作为R初学者,使用 for 循环也不合适。除此之外,我的实际数据有两列以上,因此最终看起来并不好看。我怎么能以更聪明的方式做到这一点?

干杯

3 个答案:

答案 0 :(得分:3)

这是一种方式:

library(plyr)
all.levels <- sort(levels(unlist(input)))
adply(input, 1, function(x)table(factor(unlist(x), all.levels)))
#   C1 C2 A B C D
# 1  A  B 1 1 0 0
# 2  B  D 0 1 0 1
# 3  D  C 0 0 1 1
# 4  A  D 1 0 0 1

答案 1 :(得分:1)

基础解决方案:

test <- data.frame( C1=c("A","B","D","A"),
                C2=c("B","D","C","D"),
                stringsAsFactors=FALSE
            )

uniqnames <- sort(unique(unlist(test[,1:2])))
idcols <- (t(apply(test, 1 , '%in%', x = uniqnames)) + 0) #thanks mnel!
colnames(idcols) <- uniqnames

result <- cbind(
    test,
    idcols
    )

最终数据集:

> result
  C1 C2 A B C D
1  A  B 1 1 0 0
2  B  D 0 1 0 1
3  D  C 0 0 1 1
4  A  D 1 0 0 1

答案 2 :(得分:0)

我认为您可以使用cast包中的reshape执行此操作。 我现在无法测试代码(我的R版本太旧了,目前正在重新编译它)

cast(cbind(input, 1), C1 ~ C2, sum, add.missing=T)

这实际上会计算每对出现的次数,改变这种行为用一个常量函数替换sum(可能有一种更漂亮的方式,不需要cbind / sum,但我的R很生锈)

编辑:添加了add.missing