IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

R Discussion :

Passage d'arguments variables à une fonction


Sujet :

R

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 28
    Points : 18
    Points
    18
    Par défaut Passage d'arguments variables à une fonction
    Bonjour,

    J'ai vraiment cherché mais je m'avoue incapable de résoudre ce problème qui va surement paraître hypersimple à ceux qui maîtrisent R. Juste pour mieux me situer pour ceux qui connaitraient, je suis une utilisatrice avancée de SAS et connaît particulièrement bien ses macros. Je suis complètement nouvelle sur R et essaye de résoudre des problèmes type "macro dans SAS".

    Voici le programme que j'essaye de construire :

    Au départ j'avais le code suivant (qui fonctionne très bien):
    ProfilConso <- function(Pattern,X1,X2,XHist,NbX1,NbX2,NbXH)
    {
    # Initialisation des variables de type compteur
    NbX1=0; NbX2=0; NbXH=0

    for(i in 1:NbRec) {
    Pattern[i]=0
    if (X1[i]=="O") {
    Pattern[i]=Pattern[i]+1
    NbX1=NbX1+1
    }
    if (X2[i]=="O") {
    Pattern[i]=Pattern[i]+2
    NbX2=NbX2+1
    }
    if (XHist[i]=="O") {
    Pattern[i]=Pattern[i]+4
    NbXH=NbXH+1
    }
    }
    print(NbRec); print(NbX1); print(NbX2); print(NbXH); print(Pattern); table(Pattern)
    }

    ProfilConso(ConsoAlim$CER_Pattern,ConsoAlim$CER_J1,ConsoAlim$CER_J2,ConsoAlim$CER_Hist,NbCERJ1,NbCERJ2,NbCERHist)
    ProfilConso(ConsoAlim$PAIN_Pattern,ConsoAlim$PAIN_J1,ConsoAlim$PAIN_J2,ConsoAlim$PAIN_Hist,NbPAINJ1,NbPAINJ2,NbPAINHist)
    ProfilConso(ConsoAlim$FRI_H_Pattern,ConsoAlim$FRI_H_J1,ConsoAlim$FRI_H_J2,ConsoAlim$FRI_H_Hist,NbFRI_HJ1,NbFRI_HJ2,NbFRI_HHist)
    ProfilConso(ConsoAlim$FRI_F_Pattern,ConsoAlim$FRI_F_J1,ConsoAlim$FRI_F_J2,ConsoAlim$FRI_F_Hist,NbFRI_FJ1,NbFRI_FJ2,NbFRI_FHist)
    ProfilConso(ConsoAlim$CHI_Pattern,ConsoAlim$CHI_J1,ConsoAlim$CHI_J2,ConsoAlim$CHI_Hist,NbCHIJ1,NbCHIJ2,NbCHIHist)


    etc....
    Sauf que j'ai un grand nombre de situations comme celles-ci à ré-écrire où seules quelques lettres changent dans le nom des variables que je souhaite traiter comme argument de ma fonction.

    Je souhaitais donc remplacer les différentes parties de ces noms en sous-variables et les reconstruire pour former le nom complet que j'ai à traiter :
    - "ConsoAlim" est le nom du fichier que je traite (FileName)
    - "CER" ou "PAIN" ou ("FRI_H" ou etc...) le nom du sous-item que je veux analyser
    etc...


    Voici le code où je me suis rendue:

    ProfilConso <- function(FileName,ItemAbbrev,Pattern,X1,X2,XHist,NbX1,NbX2,NbXH)
    {
    # Initialisation des variables de type compteur
    NbX1=0; NbX2=0; NbXH=0

    Pattern = paste(FileName,"$",ItemAbbrev,"_Pattern",sep=""); print(Pattern)
    X1 = paste(FileName,"$",ItemAbbrev,"_J1",sep=""); print(X1)
    X2 = paste(FileName,"$",ItemAbbrev,"_J2",sep=""); print(X2)
    XH = paste(FileName,"$",ItemAbbrev,"_Hist",sep=""); print(XH)


    for(i in 1:NbRec) {
    Pattern[i]=0
    if (X1[i]=="O") {
    Pattern[i]=Pattern[i]+1; NbX1=NbX1+1
    }
    if (X2[i]=="O") {
    Pattern[i]=Pattern[i]+2; NbX2=NbX2+1
    }
    if (XH[i]=="O") {
    Pattern[i]=Pattern[i]+4; NbXH=NbXH+1
    }
    }
    print(NbRec); print(NbX1); print(NbX2); print(NbXH); print(Pattern); table(Pattern)
    }

    ProfilConso("ConsoAlim","CER",Pattern,J1,J2,Hist,NbJ1,NbJ2,NbHist)
    Sauf que dans le code ci-dessus, si j'arrive effectivement à bien reconstruire les noms dont j'ai besoin dans les variables Pattern, X1, X2 et XH, je n'arrive pas à faire que ce n'est pas la variable Pattern ou X1 qui est traitée mais leur contenu !!

    ex.
    Si Pattern = ConsoAlim$CER_Pattern, ce n'est pas Pattern que je veux traiter mais la variable ConsoAlim$CER_Pattern...



    Merci d'avance de votre aide.

  2. #2
    Membre habitué
    Inscrit en
    Mars 2009
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 94
    Points : 147
    Points
    147
    Par défaut
    je pense avoir compris ton problème, et la solution se nomme eval(), malheureusement ce n'est pas la fonction la plus évidente quand on commence avec R.
    Voici un petit exemple pour t'aider à comprendre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=50
    eval(parse(text="a"))
    eval permet d'évaluer la chaine de caractères (ici "a") et de la transformer en une instruction ainsi tu obtiens le contenu de la variable a.

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    OK, effectivement on arrive ainsi à recréer un nom de variable, mais apparemment je ne peux pas lui attribuer un nouveau résultat.

    Voici dans un exemple plus court ce que je souhaite faire :
    Imaginons que j'ai une variable du nom de X1 (et d'Autres du même type dont seule une partie du nom change). J'aimerais pouvoir recréer ces noms dans une fonction et ensuite leur attribuer une nouvelle valeur.

    Dans l'exemple ci-dessous, je passe en paramètre le nom de X1 sous forme de 2 chaînes de caractères Str1 et Str2.

    Je reconstruis bien le nom "X1" avec paste(Str1,Str2,sep=""), puis convertis le tout comme une expression à l'aide de parse() et eval(), mais je ne peux manipuler le contenu de l'expression (normal c'est une expression et non le nom de la variable dont je veux changer le contenu).

    J'aimerais à la fin avoir remplacé la valeur dans X1 par 4.

    Des idées ?

    Ci dessous, le code qui ne fonctionne pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    X1 <- 5
     
    Test <- function(Str1,Str2) {
     
    	eval(parse(text=paste(Str1,Str2,sep=""))) <- 4
     
    	print(eval(parse(text=paste(Str1,Str2,sep=""))))
     
    }
     
    Test("X","1")
    Merci.

  4. #4
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 272
    Points : 417
    Points
    417
    Par défaut
    Bonjour,
    j'ai l'impression de ne pas comprendre du tout ce que vous voulez faire

    Pourquoi ne pas garder le "X1" obtenu avec paste et passer par parse() et eval()?

    Mon idée serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    X1 <- 5
     
    Test <- function(Str1,Str2) {
      text <- paste("X","1", sep="")
      text <- 4
      return(text)
    }
     
    X1 <- Test("X","1")
    mais je dois passer à côté du sujet, non?

    Bonne soirée

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    Ouin... c'est vrai que vu comme ça, ça ne doit pas être clair...
    Je mets ici l'ensemble de mon "vrai" code intial:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    # ************************************
    # Read a CSV File (comming from Excel)
    # ************************************
    	ConsoAlim=read.table("d:/user/data/SC/CMP/Acrylamide/BDD&Analyses_R/ConsoGroupesAliments080911.csv",header=TRUE,sep=";")
     
    # ******************************
    # Print it in the R Table Editor
    # ******************************
    	fix(ConsoAlim)
     
    # **********************************************
    # Print only 4 variables present in the DataFile 
    # **********************************************
    	ConsoAlim[,c("CER_J1", "CER_J2", "CER_Hist","CER_HistF")]
     
    # *****************************************
    # Counting and comparing previous Variables
    # *****************************************
     
    # Détermination du nombre d'enregistrement (N)
    	NbRec=length(ConsoAlim[,c("SCId")])
     
    # Analyse des profils de consommation J1/J2 et Habituellement
    # On crée une variable qui va identifier les différents profils possibles :
    # Profil  = 0 ==> Aucune consommation
    # 	  = 1 ==> Consommation en J1 seulement
    # 	  = 2 ==> Consommation en J2 seulement
    # 	  = 3 ==> Consommation en J1 et J2, mais pas habituellement ==> Problème !!!!
    # 	  = 4 ==> Consommation Habituellement, mais pas en J1/J2
    # 	  = 5 ==> Consommation en J1 et Habituellement
    # 	  = 6 ==> Consommation en J2 et Habituellement
    # 	  = 7 ==> Consommation en J1, J2 et Habituellement
     
    # _______________________________________________________________
    # Fonction "ProfilConso" permettant l'Analyse Aliment par Aliment
    # _______________________________________________________________
     
    	ProfilConso <- function(Pattern,X1,X2,XHist,NbX1,NbX2,NbXH)
    	{
    		# Initialisation des variables de type compteur
    			NbX1=0; NbX2=0; NbXH=0
     
    		for(i in 1:NbRec) {
     			Pattern[i]=0
    			if (X1[i]=="O") {
    				Pattern[i]=Pattern[i]+1
    				NbX1=NbX1+1
    			} 
    			if (X2[i]=="O") {
    				Pattern[i]=Pattern[i]+2 
    				NbX2=NbX2+1
    			}
    			if (XHist[i]=="O") {	
    				Pattern[i]=Pattern[i]+4
    				NbXH=NbXH+1
    			}
    		}
    		print(NbRec); print(NbX1); print(NbX2); print(NbXH); print(Pattern); table(Pattern)
    	}	
     
    	ProfilConso(ConsoAlim$CER_Pattern,    ConsoAlim$CER_J1,    ConsoAlim$CER_J2,    ConsoAlim$CER_Hist,    NbCERJ1,    NbCERJ2,    NbCERHist)
    	ProfilConso(ConsoAlim$PAIN_Pattern,   ConsoAlim$PAIN_J1,   ConsoAlim$PAIN_J2,   ConsoAlim$PAIN_Hist,   NbPAINJ1,   NbPAINJ2,   NbPAINHist)
    	ProfilConso(ConsoAlim$FRI_H_Pattern,  ConsoAlim$FRI_H_J1,  ConsoAlim$FRI_H_J2,  ConsoAlim$FRI_H_Hist,  NbFRI_HJ1,  NbFRI_HJ2,  NbFRI_HHist)
    	ProfilConso(ConsoAlim$FRI_F_Pattern,  ConsoAlim$FRI_F_J1,  ConsoAlim$FRI_F_J2,  ConsoAlim$FRI_F_Hist,  NbFRI_FJ1,  NbFRI_FJ2,  NbFRI_FHist)
    	ProfilConso(ConsoAlim$CHI_Pattern,    ConsoAlim$CHI_J1,    ConsoAlim$CHI_J2,    ConsoAlim$CHI_Hist,    NbCHIJ1,    NbCHIJ2,    NbCHIHist)
    	ProfilConso(ConsoAlim$CHI_AU_Pattern, ConsoAlim$CHI_AU_J1, ConsoAlim$CHI_AU_J2, ConsoAlim$CHI_AU_Hist, NbCHI_AUJ1, NbCHI_AUJ2, NbCHI_AUHist)
    	ProfilConso(ConsoAlim$BRE_Pattern,    ConsoAlim$BRE_J1,    ConsoAlim$BRE_J2,    ConsoAlim$BRE_Hist,    NbBREJ1,    NbBREJ2,    NbBREHist)
    	ProfilConso(ConsoAlim$CRAQ_Pattern,   ConsoAlim$CRAQ_J1,   ConsoAlim$CRAQ_J2,   ConsoAlim$CRAQ_Hist,   NbCRAQJ1,   NbCRAQJ2,   NbCRAQHist)
    	ProfilConso(ConsoAlim$OLI_Pattern,    ConsoAlim$OLI_J1,    ConsoAlim$OLI_J2,    ConsoAlim$OLI_Hist,    NbOLIJ1,    NbOLIJ2,    NbOLIHist)
    	ProfilConso(ConsoAlim$BISC_PE_Pattern,ConsoAlim$BISC_PE_J1,ConsoAlim$BISC_PE_J2,ConsoAlim$BISC_PE_Hist,NbBISC_PEJ1,NbBISC_PEJ2,NbBISC_PEHist)
    	ProfilConso(ConsoAlim$BISC_AU_Pattern,ConsoAlim$BISC_AU_J1,ConsoAlim$BISC_AU_J2,ConsoAlim$BISC_AU_Hist,NbBISC_AUJ1,NbBISC_AUJ2,NbBISC_AUHist)
    	ProfilConso(ConsoAlim$MAIS_Pattern,   ConsoAlim$MAIS_J1,   ConsoAlim$MAIS_J2,   ConsoAlim$MAIS_Hist,   NbMAISJ1,   NbMAISJ2,   NbMAISHist)
    	ProfilConso(ConsoAlim$CAF_Pattern,    ConsoAlim$CAF_J1,    ConsoAlim$CAF_J2,    ConsoAlim$CAF_Hist,    NbCAFJ1,    NbCAFJ2,    NbCAFHist)
    	ProfilConso(ConsoAlim$AMAN_Pattern,   ConsoAlim$AMAN_J1,   ConsoAlim$AMAN_J2,   ConsoAlim$AMAN_Hist,   NbAMANJ1,   NbAMANJ2,   NbAMANHist)
    	ProfilConso(ConsoAlim$PRU_Pattern,    ConsoAlim$PRU_J1,    ConsoAlim$PRU_J2,    ConsoAlim$PRU_Hist,    NbPRUJ1,    NbPRUJ2,    NbPRUHist)

    Ce code fonctionne très bien, mais je ne le trouve pas très pratique car je dois écrire tous les noms des variables alors que ceux-ci sont composés de parties très similaires et répétitives (ConsoAlim, _Pattern, _J1, etc).

    J'aurais donc aimé développer un code qui me permette de passer comme argument à ma fonction le nom du fichier (ConsoAlim), le sous-élément qui m'intéresse (ex. CER, PAIN, FRI_H, etc...) puis dans cette même fonction "re"-construire le nom de la variable que je veux vérifier ou incrémenter avec ces arguments.

    C'est ce que l'on arrive à faire en SAS avec les macros qui permettent de "générer" du code.

    Mais je n'arrive pas à bien expliquer.

    J'ai regardé aussi du côté de la fonction assign() qui me semblerait répondre à mes besoins, mais j'ai toujours, après reconstruction, le problème de me retrouver avec une expression et non pas avec un nom de variable.

    Est-ce un peu plus clair ?
    Merci de votre input

  6. #6
    Membre averti
    Femme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 272
    Points : 417
    Points
    417
    Par défaut
    Bonsoir,
    si j'ai bien suivi, votre ConsoAlim est un data.frame.

    Vous pouvez récupérer le nombre de colonnes parpuis jouer sur ces colonnes, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (i in 1:L){
       ConsoAlim[,i] <- ConsoAlim[,i] + 1
    }
    (ou entrer dans les paramètres de votre fonction les numéros des colonnes)

    Ce code étant très simpliste, j'ai la désagréable impression d'être encore à côté de la plaque
    J'espère, au moins, vous avoir donné une piste.
    N'hésitez pas à me le faire savoir

    Bonne continuation

    PS: les boucles for sont à éviter en R, voir ?apply

  7. #7
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    Un grand merci pour ces suggestions lilly74.

    Je suis décidément de la trop vieille école (SAS, Pascal, Fortran, VB...). J'ai beaucoup de défis devant moi avant de bien maîtriser les subtilités très intéressantes de R.

    J'ai trouvé une façon de faire qui ne me satisfait pas (sur le plan "élégance") mais ça fait la job !!!

    Merci encore et belle journée à vous.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Pb de passage d'argument dans une fonction de classe maison
    Par deusyss dans le forum Général Python
    Réponses: 10
    Dernier message: 18/03/2010, 02h14
  2. passage d'argument d'une fonction à une autre
    Par kawther dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 23/11/2008, 21h09
  3. Passage d'argument dans une fonction d'une autre classe.
    Par lavince dans le forum Général Python
    Réponses: 5
    Dernier message: 13/09/2008, 22h16
  4. Passage d'arguments à travers une fonction
    Par win-pierre dans le forum C
    Réponses: 4
    Dernier message: 01/05/2008, 13h29
  5. passage d'argument dans une fonction
    Par wadcyr8_197 dans le forum C++
    Réponses: 5
    Dernier message: 20/07/2007, 09h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo