2012-07-21 9 views
6

ho molte formule (di classe o di formulaFormula) del modulo y ~ a*b, dove a e b sono fattori.espansione interazioni tra fattori all'interno di una formula

Ho bisogno di scrivere una funzione che accetta una formula del genere e restituisce una formula con tutti i termini dell'interazione "enunciati". Ecco un esempio:

fac1 <- factor(c('a', 'a', 'b', 'b')) 
fac2 <- factor(c('c', 'd', 'c', 'd')) 
BigFormula(formula(x ~ fac1*fac2)) 

dove BigFormula rendimenti formula(x ~ a + b + c + d + a:c + a:d + b:c + b:d).

C'è un modo semplice per farlo?

(Il contesto: io sono in esecuzione molti comandi del modulo anova(mod1, mod2), dove mod2 nidi mod1, e dove il lato destro di entrambi i modelli contiene termini come fac1*fac2 Il punto di questi comandi è quello di calcolare F-statistiche. Il problema è che anova considera fac1*fac2 come tre variabili, anche se di solito rappresenta più di tre variabili. (Nel codice sopra, ad esempio, fac1*fac2 rappresenta otto variabili). Di conseguenza, anova sottovaluta il numero di restrizioni nell'annesso modello, e sovrastima i miei gradi di libertà.)

risposta

2

Come circa la seguente soluzione. Io uso un esempio più estremo di un'interazione complessa.

f = formula(y ~ a * b * c * d * e)

per precisare i termini di interazione, si estrae i termini dal valore restituito da termini.formula():

terms = attr(terms.formula(f), "term.labels")

che produce:

> terms 
[1] "a"   "b"   "c"   "d"   "e"   "a:b"  "a:c"  
[8] "b:c"  "a:d"  "b:d"  "c:d"  "a:e"  "b:e"  "c:e"  
[15] "d:e"  "a:b:c"  "a:b:d"  "a:c:d"  "b:c:d"  "a:b:e"  "a:c:e"  
[22] "b:c:e"  "a:d:e"  "b:d:e"  "c:d:e"  "a:b:c:d" "a:b:c:e" "a:b:d:e" 
[29] "a:c:d:e" "b:c:d:e" "a:b:c:d:e" 

E poi possiamo riconvertirlo in una formula:

f = as.formula(sprintf("y ~ %s", paste(terms, collapse="+")))

> f 
y ~ a + b + c + d + e + a:b + a:c + b:c + a:d + b:d + c:d + a:e + 
    b:e + c:e + d:e + a:b:c + a:b:d + a:c:d + b:c:d + a:b:e + 
    a:c:e + b:c:e + a:d:e + b:d:e + c:d:e + a:b:c:d + a:b:c:e + 
    a:b:d:e + a:c:d:e + b:c:d:e + a:b:c:d:e 
0

Abbiamo avuto un problema simile, ma un po 'più facile - in formula abbiamo ottenuto come 50 variabili e abbiamo dovuto cambiarle molto spesso; la nostra soluzione era all'interno dello script R inviarli in un loop a un file esterno facendo una formula effettiva, quindi leggete semplicemente quel file txt e incollatelo; per quanto mi ricordo potrebbe essere fatto in loop annidato in modo da rendere più formule quindi rileggere il file riga per riga; tutto sommato è sempre bene usare entrambi gli script R e bash

7

Guarda l'aiuto per formula ci possono essere cose esistenti che funzioneranno per te.

Ad esempio la formula y ~ (a + b + c + d)^2 fornisce tutti gli effetti principali e tutte le interazioni a 2 vie e la formula y ~ (a + b) * (c + d) fornisce l'espansione mostrata sopra. È inoltre possibile sottrarre termini in modo che y ~ a*b*c - a:b:c non includa l'interazione a 3 vie.

3

ho ancora ancora imparare tutti i trucchi del formula, ma se voglio formule esplicite te lo tendono ad usare sapply insieme a incollare:

# the factors 
fac1 <- factor(c('a', 'a', 'b', 'b')) 
fac2 <- factor(c('c', 'd', 'c', 'd')) 

# create all the interaction terms 
out <- sapply(levels(fac1), function(ii) { 
    sapply(levels(fac2), function(jj) { 
    paste0(ii,":",jj) 
    }) 
}) 
# along with the single terms 
terms <- c(levels(fac1), levels(fac2), as.vector(out)) 

# and create the rhs of the formula 
rhs <- paste0(terms, collapse=" + ") 

# finally add the lhs 
f <- paste0("x ~ ", rhs) 

si finisce con:

> f 
[1] "x ~ a + b + c + d + a:c + a:d + b:c + b:d" 
Problemi correlati