2013-05-21 4 views
2

Dans mon programme, je passe de manière récursive sur une liste imbriquée et j'ajoute des éléments à une liste globale que je vais retourner. Il y a quelques détails à prendre en compte, donc je ne peux pas simplement utiliser unlist.Édition récursive d'une liste dans R

formulaPart est considéré comme formula object.

Mon code est:

parseVariables <- function(formulaPart, myList){ 
    for(currentVar in as.list(formulaPart)) 
     if(typeof(currentVar == 'language' 
     parseVariables(currentVar, myList) 
     else 
     if(! toString(currentVar) %in% c(\\various characters) 
      list <- c(list, currentVar) 
    } 

J'ai vérifié que la fonction ajoute correctement les éléments à la liste quand il se doit. Le problème est que la liste perd des éléments en raison de la récursivité. Les éléments ajoutés lors d'un appel récursif interne ne sont pas enregistrés pour un autre appel récursif.

Si c'était en C++, je pourrais juste utiliser un pointeur; la même chose pour Java. Cependant, je ne comprends pas comment gérer cette erreur dans R.

+0

Pourriez-vous fournir des exemples de données avec lesquelles travailler? –

+0

Eh bien, vous ne sauvegardez pas le résultat de l'appel interne 'parseVariables'. Essayez de remplacer 'parseVariables (currentVar, myList)' par 'result <- parseVariables (currentVar, myList)' et 'list <- c (list, currentVar)' par 'list <- c (result, currentVar)'. Et vous devriez également ajouter une dernière ligne pour le résultat de la fonction, qui n'est pas très clair dans le formulaire ci-dessus. –

+0

J'ai essayé cela et il est dit que le résultat 'object 'n'est pas trouvé. Si je sauvegarde l'appel interne de 'parseVariables' à result, comment' list <- c (result, currentVar) 'va-t-il pouvoir l'utiliser. Ils sont dans différentes branches d'une instruction if-else. –

Répondre

2

R fait quelque chose comme valeur de passage, donc vous ne pouvez pas modifier (la plupart) des objets existants en les passant simplement dans une fonction. Si vous voulez ajouter quelque chose de façon récursive, une astuce serait d'utiliser un environnement à la place, qui sera passé par référence. Cela peut facilement être contraint à la liste lorsque vous avez terminé.

parseVariables <- function(formulaPart, myList){ 
    for(currentVar in as.list(formulaPart)) { 
     if(typeof(currentVar) == 'language') { 
     parseVariables(currentVar, myList) 
     } 
     else { 
     if(! toString(currentVar) %in% c(':', '+', '~')) 
      assign(toString(currentVar), currentVar, myList) 
     } 
    } 
} 

f1 <- z ~ a:b + x 
f2 <- z ~ x + y 

myList <- new.env() 

parseVariables(f1, myList) 
parseVariables(f2, mylist) 
ls(myList) 
# [1] "a" "b" "x" "z" 
as.list(myList) 
# $x 
# x 
# 
# $z 
# z 
# 
# $a 
# a 
# 
# $b 
# b 
+0

Merci. Passer par référence est exactement ce dont j'avais besoin. –