2015-07-02 9 views
5

Próbuję przekonwertować dataframe tego formatu typu:R: przekształcanie dataframe na matrycy 1 i 0

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

na matrycy tego formatu:

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

Jaki jest najlepszy sposób to zrobić w R? Próbowałem użyć reshape2, ale nie mogłem znaleźć sposobu, aby to zrobić.

Odpowiedz

4

table powinna być wystarczająca do tego:

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 

Alternatywnie, można spojrzeć na 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 
+2

Alternatywnie, naprawdę wystarczy 'cbind (mydf $ V1, Stół (mydf))' – rawr

+1

ja naprawdę nie chcę wprowadzać żadnych założeń o tym, co znajduje się w pierwszej kolumnie. Ponownie, wolę generalizować odpowiedzi na te, które odnoszą się do wąskich potrzeb pojedynczego użytkownika. – A5C1D2H2I1M1N2O1R2T1

+0

no cóż, myślę, że będziesz musiał przestać używać, ponieważ nie każdy użytkownik będzie miał V1 jako zmienną. powinieneś użyć indeksowania kolumn, które jest bardziej uogólnione – rawr

4

Może to skrót, ale to nie to samo z tym?

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 
2

nie jestem zaznajomiony z funkcji specjalnych do tego, ale mogę zrobić ...

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 

Jest to macierz zer i jedynek, w przeciwieństwie do innych odpowiedzi tak daleko. (. Oczywiście, mała różnica)

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

Inną alternatywą

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 

bardziej uproszczony jako @SamFirke zasugerował

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 
+3

Lub używając argumentu 'fill'' spread': 'dat%>% mutate (x = 1)%> spread (V2, x, fill = 0)' (wymaga również pakietu dplyr) –

2

Oto odpowiedź code-golf:

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 
0

Oto podejście z użyciem mtabulate z 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 
Powiązane problemy