2013-03-30 18 views
5

Mam dwa czynniki. współczynnik A ma 2 poziomy, czynnik B ma 3 poziomy.Tworzenie macierzy projektowej w r

Jak utworzyć następującą matrycę projektową?

 factorA1 factorA2 factorB1 factorB2 factorB3 
[1,]  1  0  1  0  0 
[2,]  1  0  0  1  0 
[3,]  1  0  0  0  1 
[4,]  0  1  1  0  0 
[5,]  0  1  0  1  0 
[6,]  0  1  0  0  1 
+0

Czy celem wiążą czynniki razem, albo jest celem, aby móc łatwo stworzyć taki rodzaj czynników? – PascalVKooten

+4

Może 'model.matrix (~ czynnik-1)' –

+1

Zapewnienie danych, które spowodowały powyższą macierz, byłoby pomocne. –

Odpowiedz

4

Masz kilka opcji:

Używaj bazy i kawałek razem sobie:

(iris.dummy<-with(iris,model.matrix(~Species-1))) 
(IRIS<-data.frame(iris,iris.dummy)) 

Albo użyć pakietu ade4 następująco:

dummy <- function(df) { 
    require(ade4) 
    ISFACT <- sapply(df, is.factor) 
    FACTS <- acm.disjonctif(df[, ISFACT, drop = FALSE]) 
    NONFACTS <- df[, !ISFACT,drop = FALSE] 
    data.frame(NONFACTS, FACTS) 
} 

dat <-data.frame(eggs = c("foo", "foo", "bar", "bar"), 
    ham = c("red","blue","green","red"), x=rnorm(4)) 
dummy(dat) 



##   x eggs.bar eggs.foo ham.blue ham.green ham.red 
## 1 0.3365302  0  1  0   0  1 
## 2 1.1341354  0  1  1   0  0 
## 3 2.0489741  1  0  0   1  0 
## 4 1.1019108  1  0  0   0  1 
+0

Ale R robi to automatycznie, jeśli nie modeluje i nie musi być jawnie wykonane przez użytkownika. –

+0

Czy istnieje bezpośrednie polecenie dla tego projektu? – Colin

+0

Nie, ale dałem ci wszystkie elementy potrzebne do zrobienia tego. 'model.matrix' w pierwszym użyciu działa na pojedyncze czynniki. Ale tak jak powiedziałem, w większości R tworzy matrycę projektowania dla ciebie, chociaż możesz to zrobić samodzielnie. Łatwo jest odzyskać matrycę z modelu po uruchomieniu. –

1

Zakładając, że dane w data.frame o nazwie dat, załóżmy, że podane są dwa czynniki, jak na tym egzaminie ple:

> dat <- data.frame(f1=sample(LETTERS[1:3],20,T),f2=sample(LETTERS[4:5],20,T),id=1:20) 
> dat 
    f1 f2 id 
1 C D 1 
2 B E 2 
3 B E 3 
4 A D 4 
5 C E 5 
6 C E 6 
7 C D 7 
8 B E 8 
9 C D 9 
10 A D 10 
11 B E 11 
12 C E 12 
13 B D 13 
14 B E 14 
15 A D 15 
16 C E 16 
17 C D 17 
18 C D 18 
19 B D 19 
20 C D 20 
> dat$f1 
[1] C B B A C C C B C A B C B B A C C C B C 
Levels: A B C 
> dat$f2 
[1] D E E D E E D E D D E E D E D E D D D D 
Levels: D E 

Można użyć outer dostać matrycę jak pokazałeś, dla każdego czynnika:

> F1 <- with(dat, outer(f1, levels(f1), `==`)*1) 
> colnames(F1) <- paste("f1",sep="=",levels(dat$f1)) 
> F1 
     f1=A f1=B f1=C 
[1,] 0 0 1 
[2,] 0 1 0 
[3,] 0 1 0 
[4,] 1 0 0 
[5,] 0 0 1 
[6,] 0 0 1 
[7,] 0 0 1 
[8,] 0 1 0 
[9,] 0 0 1 
[10,] 1 0 0 
[11,] 0 1 0 
[12,] 0 0 1 
[13,] 0 1 0 
[14,] 0 1 0 
[15,] 1 0 0 
[16,] 0 0 1 
[17,] 0 0 1 
[18,] 0 0 1 
[19,] 0 1 0 
[20,] 0 0 1 

teraz zrobić to samo dla drugiego czynnika:

> F2 <- with(dat, outer(f2, levels(f2), `==`)*1) 
> colnames(F2) <- paste("f2",sep="=",levels(dat$f2)) 

I cbind aby uzyskać ostateczny wynik:

> cbind(F1,F2) 
0

to proces, który lm i inne używane w tle do konwersji dla Ciebie.

dat <- data.frame(f1=sample(LETTERS[1:3],20,T),f2=sample(LETTERS[4:5],20,T),id=1:20) 
dat 

model.matrix(~dat$f1 + dat$f2) 

Tworzy zmienną INTERCEPT jako kolumnę 1, ale możesz ją łatwo usunąć, jeśli potrzebujesz.

model.matrix(~dat$f1 + dat$f2)[,-1] 

Edit: Teraz widzę, że to jest w zasadzie taki sam jak jeden z innych uwag, ale bardziej zwięzły.

+0

Idiomatyczne wykluczenie przechwycenia dodaje "0" do prawej strony, jak w 'model.matrix (~ 0 + f1 + f2, dat)'. – effel

0

Rozbudowa i uogólnianie @ odpowiedź Ferdinand.kraft za:

dat <- data.frame(
    f1 = sample(LETTERS[1:3], 20, TRUE), 
    f2 = sample(LETTERS[4:5], 20, TRUE), 
    row.names = paste0("id_", 1:20)) 

covariates <- c("f1", "f2") # in case you have other columns that you don't want to include in the design matrix 
design <- do.call(cbind, lapply(covariates, function(covariate){ 
    apply(outer(dat[[covariate]], unique(dat[[covariate]]), FUN = "=="), 2, as.integer) 
})) 
rownames(design) <- rownames(dat) 
colnames(design) <- unlist(sapply(covariates, function(covariate) unique(dat[[covariate]]))) 
design <- design[, !duplicated(colnames(design))] # duplicated colnames happen sometimes 
design 
#  C A B D E 
# id_1 1 0 0 1 0 
# id_2 0 1 0 1 0 
# id_3 0 0 1 1 0 
# id_4 1 0 0 1 0 
# id_5 0 1 0 1 0 
# id_6 0 1 0 0 1 
# id_7 0 0 1 0 1