R:将数据帧重塑为1'的矩阵;s和0';s

R:将数据帧重塑为1'的矩阵;s和0';s,r,R,我正在尝试转换此类型的数据帧格式: V1 V2 1 a 2 a 3 b 4 c 5 c 转换为这种格式的矩阵: V1 a b c 1 1 0 0 2 1 0 0 3 0 1 0 4 0 0 1 5 0 0 1 在R中实现这一点的最佳方法是什么?我已尝试使用Reforme2,但找不到执行此操作的方法。表应足以满足此要求: with(mydf, cbind(V1, table(1:nrow(mydf),

我正在尝试转换此类型的数据帧格式:

  V1 V2
  1  a
  2  a
  3  b
  4  c
  5  c
转换为这种格式的矩阵:

  V1 a  b  c
  1  1  0  0
  2  1  0  0
  3  0  1  0
  4  0  0  1
  5  0  0  1

在R中实现这一点的最佳方法是什么?我已尝试使用Reforme2,但找不到执行此操作的方法。

应足以满足此要求:

with(mydf, cbind(V1, table(1:nrow(mydf), V2)))
##   V1 a b c
## 1  1 1 0 0
## 2  2 1 0 0
## 3  3 0 1 0
## 4  4 0 0 1
## 5  5 0 0 1
或者,您可以查看
model.matrix

cbind(mydf["V1"], model.matrix(~V2 + 0, mydf))
##   V1 V2a V2b V2c
## 1  1   1   0   0
## 2  2   1   0   0
## 3  3   0   1   0
## 4  4   0   0   1
## 5  5   0   0   1

也许是一条捷径,但这和这不一样吗

library(reshape2)
dcast(dat, V1 ~ V2, length )
Using V2 as value column: use value.var to override.
  V1 a b c
1  1 1 0 0
2  2 1 0 0
3  3 0 1 0
4  4 0 0 1
5  5 0 0 1

我不熟悉这个的特殊功能,但我可能会

uv <- unique(DF$V2)
m  <- matrix(0L,nrow(DF),length(uv),dimnames=list(DF$V1,uv))
m[ cbind(1:nrow(m), match(DF$V2,uv)) ] <- 1L
另一种选择

library(tidyr)
out = cbind(dat[1], 
      apply(spread(dat, V2, V2)[-1], 2, 
            function(x) ifelse(is.na(x), 0, 1)))

#  V1 a b c
#1  1 1 0 0
#2  2 1 0 0
#3  3 0 1 0
#4  4 0 0 1
#5  5 0 0 1
正如@SamFirke所建议的那样更加简化

library(dplyr)
library(tidyr)
dat %>% mutate(x = 1) %>% spread(V2, x, fill = 0)

#  V1 a b c
#1  1 1 0 0
#2  2 1 0 0
#3  3 0 1 0
#4  4 0 0 1
#5  5 0 0 1

下面是一个密码高尔夫答案:

model.matrix(~.-1,df)
##   V1 V2a V2b V2c
## 1  1   1   0   0
## 2  2   1   0   0
## 3  3   0   1   0
## 4  4   0   0   1
## 5  5   0   0   1

这里有一种使用
mtabulate
的方法,来自qdapTools

library(qdapTools)
data.frame(dat[, 1, drop=F], mtabulate(setNames(dat[[2]], dat[[1]])))

##   V1 a b c
## 1  1 1 0 0
## 2  2 1 0 0
## 3  3 0 1 0
## 4  4 0 0 1
## 5  5 0 0 1

或者,您只需要
cbind(mydf$V1,table(mydf))
我不想对第一列中的内容做任何假设。同样,我更喜欢概括的答案,而不是满足单个用户需求的答案。哦,那么我想你需要停止使用with,因为不是每个用户都将V1作为变量。您应该使用更通用的列索引,或者使用一个函数,该函数在列中搜索字符串变量,并将其与可能存在或可能不存在的其他列进行比较,并在不考虑数据结构的情况下对用户真正想要使用的列进行最佳猜测。这将是最好的解决方案是的,只要
V1
不包含重复值,@rawr建议
table(mydf)
就可以了。但这是一个假设。或者使用
spread
fill
参数:
dat%>%mutate(x=1)%%>%spread(V2,x,fill=0)
(还需要dplyr包)
library(qdapTools)
data.frame(dat[, 1, drop=F], mtabulate(setNames(dat[[2]], dat[[1]])))

##   V1 a b c
## 1  1 1 0 0
## 2  2 1 0 0
## 3  3 0 1 0
## 4  4 0 0 1
## 5  5 0 0 1