2012-04-19 4 views
5

Supponiamo che io ho una formula seguente:Come selezionare una parte di formula in formula in R?

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

oggetto Dato fr c'è una funzione in R che restituisce myfun(x)? Ho scritto la mia funzione (codice sotto) che fondamentalmente fa ciò di cui ho bisogno, ma forse c'è un modo standard per farlo?

Il codice per la mia funzione:

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

Ecco alcuni esempi:

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

risposta

7

Non è sicuro questa è la cosa migliore, ma si può farlo:

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

poi ,

> 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

Abbastanza vicino a quello che stavo cercando. Le formule di analisi sono divertenti, ma è bello avere qualcun altro che le analizzi per me :) – mpiktas

+0

Mi chiedo: forse c'è un modo per restituire la definizione di 'f' come oggetto stringa, cioè' fname <- "formula (y ~ myfun (cose) + z) "'. Quindi puoi semplicemente fare un 'grep' per tutto tra" ~ "e") ". –

+0

@CarlWitthoft, ho bisogno anche delle cose tra parentesi. Convertire la formula in stringa e l'uso di grep non è una buona idea secondo me. – mpiktas

2

C'è un argomento specials su terms che consente di contrassegnare le funzioni con nome nella formula per l'estrazione per posizione.

Quindi, è possibile scrivere

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])) 
} 

Allora i vostri casi di test danno

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

Ma, si può anche fare

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

$myfun2 
myfun(x2) 

$yourfun 
yourfun(zz) 

Dove si potrebbe colpire il unlist di avere questo nidificato invece con la funzione denominata.