2012-07-05 43 views
6

dữ liệu Cho rằng trông giống như:Chuyển đổi một cột yếu tố để nhiều cột boolean

library(data.table) 
DT <- data.table(x=rep(1:5, 2)) 

Tôi muốn chia dữ liệu này thành 5 cột boolean chỉ ra sự hiện diện của mỗi số.

tôi có thể làm điều này như thế này:

new.names <- sort(unique(DT$x)) 

DT[, paste0('col', new.names) := lapply(new.names, function(i) DT$x==i), with=FALSE] 

Nhưng điều này sử dụng một pesky lapply mà có lẽ chậm hơn so với phương án data.table và các giải pháp này đập vào mắt tôi như không phải là rất "data.table-ish".

Có cách nào tốt hơn và/hoặc nhanh hơn để tạo các cột mới này không?

+1

Would một cái gì đó như 'model.matrix' thể hữu ích? 'model.matrix (~ cols-1)' – BenBarnes

Trả lời

8

Làm thế nào về 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" 

Rõ ràng, bạn có thể đặt model.matrix vào [.data.table để cung cấp kết quả tương tự. Không chắc chắn nếu nó sẽ nhanh hơn:

DT[,model.matrix(~factor(x)-1)] 
+0

Tất nhiên có một câu trả lời từ cơ sở R ... Cảm ơn! – Justin

2

Ngoài ra còn có nnet::class.ind

library(nnet) 

cbind(DT, setnames(as.data.table(DT[, class.ind(x)]),paste0('col', unique(DT$x)))) 
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) 
Các vấn đề liên quan