1

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

我的输入如下所示:

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循环也不合适。除此之外,我的实际数据不止两列,因此最终看起来不太好。我将如何以更聪明的方式做到这一点?

干杯

4

3 回答 3

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
于 2012-07-10T00:52:09.703 回答
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
于 2012-07-10T03:13:37.673 回答
0

我认为你可以castreshape包中做到这一点。我现在无法测试代码(我的 R 版本太旧,目前正在重新编译)

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

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

编辑:添加 add.missing

于 2012-07-10T01:01:18.330 回答