Extraer información de fórmula condicional
Pregunta
Me gustaría escribir una función de R que acepte una fórmula como primer argumento, similar a lm () o GLM () y amigos. En este caso, se trata de una función que toma una trama de datos y escribe un archivo en SVMLight formato, que tiene esta forma general:
<line> .=. <target> <feature>:<value> <feature>:<value> ... <feature>:<value> # <info>
<target> .=. +1 | -1 | 0 | <float>
<feature> .=. <integer> | "qid"
<value> .=. <float>
<info> .=. <string>
Por ejemplo, la siguiente trama de datos:
result qid f1 f2 f3 f4 f5 f6 f7 f8
1 -1 1 0.0000 0.1253 0.0000 0.1017 0.00 0.0000 0.0000 0.9999
2 -1 1 0.0098 0.0000 0.0000 0.0000 0.00 0.0316 0.0000 0.3661
3 1 1 0.0000 0.0000 0.1941 0.0000 0.00 0.0000 0.0509 0.0000
4 -1 2 0.0000 0.2863 0.0948 0.0000 0.34 0.0000 0.7428 0.0608
5 1 2 0.0000 0.0000 0.0000 0.4347 0.00 0.0000 0.9539 0.0000
6 1 2 0.0000 0.7282 0.9087 0.0000 0.00 0.0000 0.0000 0.0355
sería representado como sigue:
-1 qid:1 2:0.1253 4:0.1017 8:0.9999
-1 qid:1 1:0.0098 6:0.0316 8:0.3661
1 qid:1 3:0.1941 7:0.0509
-1 qid:2 2:0.2863 3:0.0948 5:0.3400 7:0.7428 8:0.0608
1 qid:2 4:0.4347 7:0.9539
1 qid:2 2:0.7282 3:0.9087 8:0.0355
La función me gustaría escribir sería llamado algo como esto:
write.svmlight(result ~ f1+f2+f3+f4+f5+f6+f7+f8 | qid, data=mydata, file="out.txt")
O incluso
write.svmlight(result ~ . | qid, data=mydata, file="out.txt")
Pero no puedo encontrar la manera de utilizar model.matrix()
y / o model.frame()
saber qué columnas se supone que debe escribir. ¿Son estas las cosas bien para estar mirando?
Cualquier ayuda muy apreciada!
Solución
respuesta parcial. Puede subíndice un objeto fórmula para obtener un árbol de análisis sintáctico de la fórmula:
> f<-a~b+c|d
> f[[1]]
`~`
> f[[2]]
a
> f[[3]]
b + c | d
> f[[3]][[1]]
`|`
> f[[3]][[2]]
b + c
> f[[3]][[3]]
d
Ahora todo lo que necesita es el código para recorrer este árbol.
ACTUALIZACIÓN:. He aquí un ejemplo de una función que recorre el árbol
walker<-function(formu){
if (!is(formu,"formula"))
stop("Want formula")
lhs <- formu[[2]]
formu <- formu[[3]]
if (formu[[1]]!='|')
stop("Want conditional part")
condi <- formu[[3]]
flattener <- function(f) {if (length(f)<3) return(f);
c(Recall(f[[2]]),Recall(f[[3]]))}
vars <- flattener(formu[[2]])
list(lhs=lhs,condi=condi,vars=vars)
}
walker(y~a+b|c)
También mirar la documentación de terms.formula
y terms.object
. Si examina el código para algunas funciones que toman fórmulas condicionales pueden ayudar, por ejemplo. la función lmer
en el paquete lme4
.
Otros consejos
He utilizado
formu.names <- all.vars(formu)
Y.name <- formu.names[1]
X.name <- formu.names[2]
block.name <- formu.names[3]
En el código que he escrito acerca de hacer un post-hoc para una prueba de Friedman:
http: //www.r-statistics.com/2010/02/post-hoc-analysis-for-friedmans-test-r-code/
Pero sólo funcionará para: Y`X | bloque
Espero una respuesta mejor que otros den.