给出的数据如下:
library(data.table)
DT <- data.table(x=rep(1:5, 2))
我想将这些数据拆分为5个布尔列,表示每个数字的存在。
我可以这样做:
new.names <- sort(unique(DT$x))
DT[, paste0('col', new.names) := lapply(new.names, function(i) DT$x==i), with=FALSE]
但这会使用一个令人讨厌的lapply
,这可能比data.table替代方案慢,这个解决方案让我觉得不是很“data.table-ish”。
是否有更好和/或更快的方法来创建这些新列?
答案 0 :(得分:9)
model.matrix
怎么样?
model.matrix(~factor(x)-1,data=DT)
factor(x)1 factor(x)2 factor(x)3 factor(x)4 factor(x)5
1 1 0 0 0 0
2 0 1 0 0 0
3 0 0 1 0 0
4 0 0 0 1 0
5 0 0 0 0 1
6 1 0 0 0 0
7 0 1 0 0 0
8 0 0 1 0 0
9 0 0 0 1 0
10 0 0 0 0 1
attr(,"assign")
[1] 1 1 1 1 1
attr(,"contrasts")
attr(,"contrasts")$`factor(x)`
[1] "contr.treatment"
显然,您可以将model.matrix
放入[.data.table
以获得相同的结果。不确定它是否会更快:
DT[,model.matrix(~factor(x)-1)]
答案 1 :(得分:2)
还有nnet::class.ind
library(nnet)
cbind(DT, setnames(as.data.table(DT[, class.ind(x)]),paste0('col', unique(DT$x))))
答案 2 :(得分:0)
library(data.table)
DT <- data.table(x=rep(1:5, 2))
# add column with id
DT[, id := seq.int(nrow(DT))]
# cast long table into wide
DT.wide <- dcast(DT, id ~ x, value.var = "x", fill = 0, fun = function(x) 1)