2012-07-21 13 views
6

I tienen muchas fórmulas (de clase formula o Formula) de la forma y ~ a*b, donde a y b son factores.expansión interacciones de los factores dentro de una fórmula

Necesito escribir una función que tome tal fórmula y devuelva una fórmula con todos los términos en la interacción "deletreado". Aquí está un ejemplo:

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

donde BigFormula vuelve formula(x ~ a + b + c + d + a:c + a:d + b:c + b:d).

¿Hay una manera simple de hacer esto?

(El contexto: Me postulo muchos de los comandos de la forma anova(mod1, mod2), donde mod2 nidos en mod1, y donde el lado derecho de ambos modelos contiene términos como fac1*fac2 El punto de estos comandos es calcular estadísticos-F. El problema es que anova trata fac1*fac2 como tres variables, aunque generalmente representa más de tres variables (en el código anterior, por ejemplo, fac1*fac2 representa ocho variables). Como resultado, anova subestima el número de restricciones en el anidado modelo, y sobreestima mis grados de libertad.)

Respuesta

2

¿Qué tal la siguiente solución. Utilizo un ejemplo más extremo de una interacción compleja.

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

Para deletrear los términos de interacción, extraemos los términos del valor devuelto por términos.fórmula():

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

que 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" 

Y entonces podemos convertir de nuevo a una fórmula:

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

Tenemos un problema similar, pero un poco más fácil - en la fórmula obtuvimos como 50 variables y tuvimos que cambiarlas muy a menudo; nuestra solución fue guiarlos dentro de R enviarlos en un bucle a un archivo externo haciendo una fórmula real y luego leer ese archivo txt y pegarlo; por lo que recuerdo, podría hacerse en bucle anidado para hacer más fórmulas y luego volver a leer el archivo línea por línea; en general, siempre es bueno utilizar los dos scripts R y bash

7

Mira la ayuda para formula puede haber cosas existentes que funcionen para usted.

Por ejemplo, la fórmula y ~ (a + b + c + d)^2 le dará todos los efectos principales y todas las interacciones bidireccionales y la fórmula y ~ (a + b) * (c + d) proporciona la expansión que muestra arriba. También puede restar los términos para que y ~ a*b*c - a:b:c no incluya la interacción de 3 vías.

3

Todavía aún tienen que aprender todos los trucos de la fórmula, pero si quiero fórmulas explícitas que tenderá a utilizar sapply junto con pegar:

# 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) 

Terminamos con:

> f 
[1] "x ~ a + b + c + d + a:c + a:d + b:c + b:d" 
Cuestiones relacionadas