2012-12-16 51 views
12

我想将我的数据框转换为矩阵,将单因子列扩展为多个矩阵,并根据因子分配1/0。例如将R因子转换为二进制矩阵值

C1 C2 C3 
A 3 5 
B 3 4 
A 1 1 

应该变成像

C1_A C1_B C2 C3 
1  0 3 5 
0  1 3 4 
1  0 1 1 

如何在R中可以做到这一点?我试过data.matrix,as.matrix,它没有返回我想要的东西。他们将“整数”值分配给单个因子列,没有扩展。

回答

15

假设dat是您的数据帧:

cbind(dat, model.matrix(~ 0 + C1, dat)) 

    C1 C2 C3 C1A C1B 
1 A 3 5 1 0 
2 B 3 4 0 1 
3 A 1 1 1 0 

该解决方案适用于任何数量的因子水平,并没有手动指定列名。

如果你想排除列C1,你可以使用这个命令:

cbind(dat[-1], model.matrix(~ 0 + C1, dat)) 
+10

OP似乎想要'model.matrix(〜。+ 0,dat)'。 – Roland

+0

@Roland好主意+1。这会更容易。 –

+1

@Sven,这工作,谢谢。尽管(除了C1_A,C1_B列),它仍然保持C1的结果,任何想法我将如何删除原始列?尽管(也许)这是一个更为普遍的问题,但只是一种简单的R表达方式,即“给我所有列除_that_之外”都可以。 – user423805

2

让我们把你的data.frame df

library(reshape2) 
dcast(df,C2*C3~C1,fill=0,length) 

    C2 C3 A B 
1 1 1 1 0 
2 3 4 0 1 
3 3 5 1 0 
+1

感谢两个答案..心不是有没有办法做到这一点的转换不指定任何列名,如C1?简单地说,转换(DF),它会处理因素。 lm()以及其他回归方法在内部是否正确? – user423805

3
dat <- read.table(text =' C1 C2 C3 
A 3 5 
B 3 4 
A 1 1',header=T) 

使用转换

transform(dat,C1_A =ifelse(C1=='A',1,0),C1_B =ifelse(C1=='B',1,0))[,-1] 
    C2 C3 C1_A C1_B 
1 3 5 1 0 
2 3 4 0 1 
3 1 1 1 0 

或者获得更多的flexbility,与within

within(dat,{ 
      C1_A =ifelse(C1=='A',1,0) 
      C1_B =ifelse(C1=='B',1,0)}) 

    C1 C2 C3 C1_B C1_A 
1 A 3 5 0 1 
2 B 3 4 1 0 
3 A 1 1 0 1