2012-04-19 10 views
5

Załóżmy, że ma następujący wzór:Jak wybrać część wzoru we wzorze w R?

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

fr dany obiekt nie jest funkcją R, która zwraca na myfun(x)? Napisałem swoją własną funkcję (kod poniżej), który zasadniczo robi to, czego potrzebuję, ale może jest jakiś standardowy sposób robienia tego?

Kod dla mojej funkcji:

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

Oto kilka przykładów:

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

Odpowiedz

7

Nie wiem, to jest najlepszy, ale można to zrobić przez:

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

następnie ,

> 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

Bardzo blisko tego, czego szukałem. Parsowanie formuł jest fajne, ale miło jest mieć kogoś, kto je dla mnie przetworzył :) – mpiktas

+0

Zastanawiam się: być może istnieje sposób na zwrócenie definicji 'f' jako obiektu typu string, tj.' Fname <- "formuła (y ~ myfun (stuff) + z) ". Następnie możesz po prostu zrobić "grep" dla wszystkiego pomiędzy "~" i ")". –

+0

@CarlWitthoft, Potrzebuję również rzeczy w nawiasach. Przekonwertowanie formuły na string i używanie grep nie jest moim zdaniem dobrym pomysłem. – mpiktas

2

Istnieje jeden argument specials dla terms, który umożliwia oznaczenie nazwanych funkcji w formule w celu wyodrębnienia według pozycji.

Tak, można napisać

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

Zmodyfikowane testami dać

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

Ale można też zrobić

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

$myfun2 
myfun(x2) 

$yourfun 
yourfun(zz) 

Gdzie można uderzyć unlist mieć to zagnieżdżona przez nazwaną funkcję zamiast.

Powiązane problemy