0

假设我在 a 中有一个列,matrix如下data.frame所示:

df <- data.frame(col1=sample(letters[1:3], 10, TRUE))

我想将其扩展到多列,列中的每个级别一个,0/1 条目表示每一行是否存在级别

newdf <- data.frame(a=rep(0, 10), b=rep(0,10), c=rep(0,10))
for (i in 1:length(levels(df$col1))) {
  curLetter <- levels(df$col1)[i]
  newdf[which(df$col1 == curLetter), curLetter] <- 1
}
newdf

我知道有一个简单聪明的解决方案,但我不知道它是什么。我试过expand.griddf,它会按原样返回。同样melt在原样退回的reshape2包裹中。我也尝试过,但它抱怨尺寸不正确或未定义的列。dfdfreshape

4

2 回答 2

2

显然,model.matrix这里是最直接的候选者,但在这里,我将提出三个备选方案:tablelapplydcast( 最后一个,因为这个问题被标记为

table

table(sequence(nrow(df)), df$col1)
#     
#      a b c
#   1  1 0 0
#   2  0 1 0
#   3  0 1 0
#   4  0 0 1
#   5  1 0 0
#   6  0 0 1
#   7  0 0 1
#   8  0 1 0
#   9  0 1 0
#   10 1 0 0

lapply

newdf <- data.frame(a=rep(0, 10), b=rep(0,10), c=rep(0,10))
newdf[] <- lapply(names(newdf), function(x) 
    { newdf[[x]][df[,1] == x] <- 1; newdf[[x]] })
newdf
#    a b c
# 1  1 0 0
# 2  0 1 0
# 3  0 1 0
# 4  0 0 1
# 5  1 0 0
# 6  0 0 1
# 7  0 0 1
# 8  0 1 0
# 9  0 1 0
# 10 1 0 0

dcast

library(reshape2)
dcast(df, sequence(nrow(df)) ~ df$col1, fun.aggregate=length, value.var = "col1")
#    sequence(nrow(df)) a b c
# 1                   1 1 0 0
# 2                   2 0 1 0
# 3                   3 0 1 0
# 4                   4 0 0 1
# 5                   5 1 0 0
# 6                   6 0 0 1
# 7                   7 0 0 1
# 8                   8 0 1 0
# 9                   9 0 1 0
# 10                 10 1 0 0
于 2013-10-03T07:33:34.343 回答
1

这很容易model.matrix

model.matrix(~ df$col1 + 0)

该术语+ 0表示不包括截距。因此,您会收到每个因子水平的虚拟变量。

结果:

   df$col1a df$col1b df$col1c
1         0        0        1
2         0        1        0
3         0        0        1
4         1        0        0
5         0        1        0
6         1        0        0
7         1        0        0
8         0        1        0
9         1        0        0
10        0        1        0
attr(,"assign")
[1] 1 1 1
attr(,"contrasts")
attr(,"contrasts")$`df$col1`
[1] "contr.treatment"
于 2013-10-03T07:07:40.150 回答