2012-04-19 15 views
5

Supongamos que tengo una siguiente fórmula:¿Cómo seleccionar una parte de fórmula en fórmula en R?

fr <- formula(y~myfun(x)+z) 

objeto dado fr hay una función en R que devuelve myfun(x)? Escribí mi propia función (código a continuación) que básicamente hace lo que necesito, pero ¿hay alguna forma estándar de hacerlo?

La código para mi función de:

selectmds <- function(expr,funcn) { 
    if(length(expr)>2) { 
     a <- expr[[2]] 
     b <- expr[[3]] 
     if(length(a)>1) { 
      if(as.name(a[[1]])==funcn) { 
       if(length(grep(funcn,all.names(b)))>0) { 
        return(list(a,selectmds(b,funcn))) 
       } 
       else return(list(a)) 
      } 
     } 
     if(length(b)>1) { 
      if(as.name(b[[1]])==funcn) { 
       if(length(grep(funcn,all.names(a)))>0) { 
        return(list(b,selectmds(a,funcn))) 
       } 
       else return(list(b)) 
      } 
     } 
     for(i in 2:length(expr)) { 
      if(length(grep(funcn,all.names(expr[[i]])))>0)return(selectmds(expr[[i]],funcn)) 
     } 
    } 
    return(NULL) 
} 

Aquí hay varios ejemplos:

> selectmds(formula(y~myfun(x)+z),"myfun") 
[[1]] 
myfun(x) 


> unlist(selectmds(formula(y~myfun(x)+z+myfun(zz)),"myfun")) 
[[1]] 
myfun(zz) 

[[2]] 
myfun(x) 

Respuesta

7

No estoy seguro es mejor, pero puede hacerlo por:

f <- function(fm, fun) { 
    l <- as.list(attr(terms(fm), "variables"))[-1] 
    l[grep(fun, l)] 
} 

entonces ,

> f(formula(y~myfun(x)+z),"myfun") 
[[1]] 
myfun(x) 

> f(formula(y~myfun(x)+z+myfun(zz)),"myfun") 
[[1]] 
myfun(x) 

[[2]] 
myfun(zz) 
+0

Bastante cerca de lo que estaba buscando. Analizar fórmulas es divertido, pero es bueno tener a alguien más para analizarlas :) – mpiktas

+0

Me pregunto: quizás haya una forma de devolver la definición de 'f' como un objeto de cadena, es decir,' fname <- "fórmula (y ~ myfun (cosas) + z) "'. Entonces puedes hacer un 'grep' para todo entre" ~ "y") ". –

+0

@CarlWitthoft, necesito las cosas entre paréntesis también. Convertir la fórmula en cadena y usar grep no es una buena idea en mi opinión. – mpiktas

2

Hay un argumento specials en terms que le permite marcar funciones nombradas en la fórmula de extracción por posición.

Por lo tanto, se puede escribir

selectmds<-function(form,fn) { 
    tt<-terms(form,specials=fn); 
    idx<-attr(tt,"specials"); 
    v<-as.list(attr(tt,"variables"))[-1]; 
    unlist(lapply(idx,function(i) v[i])) 
} 

A continuación, sus casos de prueba dan

> selectmds(formula(y~myfun(x)+z),"myfun") 
$myfun 
myfun(x) 

> selectmds(formula(y~myfun(x)+z+myfun(zz)),"myfun") 
$myfun1 
myfun(x) 

$myfun2 
myfun(zz) 

embargo, también se puede hacer

> selectmds(formula(y~myfun(x)+myfun(x2)+z+yourfun(zz)),c("myfun","yourfun")) 
$myfun1 
myfun(x) 

$myfun2 
myfun(x2) 

$yourfun 
yourfun(zz) 

Cuando usted podría golpear la unlist tener esta anidada por el nombre de la función en su lugar.

Cuestiones relacionadas