2017-10-20 4 views
1

J'ai un problème pour extraire les arguments de fonction dans l'affaire R.Expression régulière pour extraire les arguments de fonction dans R

x="theme(legend.position='bottom', 
    legend.margin=(t=0,r=0,b=0,l=0,unit='mm'), 
    legend.background=element_rect(fill='red',size=rel(1.5)), 
    panel.background=element_rect(fill='red'), 
    legend.position='bottom')" 

Ce que je veux:

[1]legend.position='bottom' 
[2]legend.margin=(t=0,r=0,b=0,l=0,unit='mm') 
[3]legend.background=element_rect(fill='red',size=rel(1.5)) 
[4]panel.background=element_rect(fill='red') 
[5]legend.position='bottom' 

J'ai essayé plusieurs expressions régulières sans succès, y compris followings :

strsplit(x,",(?![^()]*\\))",perl=TRUE)

S'il vous plaît aidez-moi!

+4

Je vais vous reculer d'un pas. Comment avez-vous fini avec le code R/ggplot enregistré en tant que texte? Je suppose qu'il doit y avoir un moyen plus facile de le faire en premier lieu .. – thelatemail

+0

En fait, je fais un dieu brillant pour enseigner ggplot2. Je vais faire cette application brillante dans un package RStudio addin et sortir sur CRAN dans quelques jours. –

+0

J'essaie, mais c'est un peu complexe – pirs

Répondre

0

Arf, je suis vraiment désolé mais je dois aller travailler, je vais continuer plus tard mais pour l'instant je laisse ma façon de résoudre partiellement: theme\(([a-z.]*=['a-z]*)|([a-z._]*=[a-z0-9=,'_.()]*)*\,\)?

Il ne manque que la dernière partie ..

Voici la page regex101: https://regex101.com/r/BZpcW0/2

A plus tard.

+0

Merci beaucoup. J'essaye. –

1

Je pense que la meilleure réponse ici pourrait être pas essayer d'utiliser une regex pour analyser votre appel de fonction. Comme son nom l'indique, les expressions régulières nécessitent un langage régulier. Votre appel de fonction n'est pas régulier, car il a des parenthèses imbriquées. Je vois actuellement une profondeur max imbriquée de deux, mais qui sait si cela pourrait devenir plus profond à un moment donné.

Je recommanderais plutôt d'écrire un simple analyseur. Vous pouvez utiliser une pile ici, pour garder une trace des parenthèses. Et vous ne feriez que fractionner un paramètre si toutes les parenthèses étaient fermées, ce qui implique que vous n'êtes pas au milieu d'un paramètre, excepté peut-être le tout premier.

0

Merci pour vos conseils. J'ai analysé les phrases et j'ai trouvé les arguments sous forme de liste. Voici ma solution.

x<-"theme(legend.margin=margin(t=0,r=0,b=0,l=0,unit='mm'), 
legend.background=element_rect(fill='red',size=rel(1.5)), 
panel.background=element_rect(fill='red'), 
legend.position='bottom')" 

extractArgs=function(x){ 

result<-tryCatch(eval(parse(text=x)),error=function(e) return("error")) 

if("character" %in% class(result)){ 
    args=character(0) 
} else { 
    if(length(names(result)>0)){ 
     pos=unlist(str_locate_all(x,names(result))) 
     pos=c(sort(pos[seq(1,length(pos),by=2)]),nchar(x)+1) 

     args=c() 
     for(i in 1:(length(pos)-1)){ 
     args=c(args,substring(x,pos[i],lead(pos)[i]-2)) 
     } 

    } else{ 
     args=character(0) 
    } 
} 
args 
}