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 :

écrire fonction simple


Sujet :

R

  1. #1
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2011
    Messages : 84
    Points : 51
    Points
    51
    Par défaut écrire fonction simple
    Bonjour
    Je travaille principalement avec une dizaine de séries temporelles. Jusqu’à maintenant, je les lisais une par une avec la fonction « read.csv » et en assignant un nom à chacune de ces séries.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    AA <- read.csv("AAAA.csv"
    			, header=TRUE, 
    			, sep=";", dec = ".")
    	AA[[1]] <- as.POSIXct(strptime(AA[[1]], "%d.%m.%Y %H:%M"))
    BB <- read.csv("BBBB.csv"
    			, header=TRUE, 
    			, sep=";", dec = ".")
    	BB[[1]] <- as.POSIXct(strptime(BB[[1]], "%d.%m.%Y %H:%M"))
    Etc….
    Puis j’ai pensé à mettre toutes ces lignes de « read.csv » dans une grande fonction afin d’être un peu plus rapide.

    J’ai donc fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Readata <- function() {
    AA <- read.csv("AAAA.csv"
    			, header=TRUE, 
    			, sep=";", dec = ".")
    	AA[[1]] <- as.POSIXct(strptime(AA[[1]], "%d.%m.%Y %H:%M"))
    BB <- read.csv("BBBB.csv"
    			, header=TRUE, 
    			, sep=";", dec = ".")
    	BB[[1]] <- as.POSIXct(strptime(BB[[1]], "%d.%m.%Y %H:%M"))
    }
    Seulement, je rencontre quelques problèmes. Mes data.frame n’existent pas une fois que j’implémente la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Readata()
    str(AA)
    Error in str(AA) : object 'AA' not found
    J’ai essayé plusieurs choses.
    à la fin de la fonction par exemple (je n'ai donc pas bien compris à quoi sert "return"), qui m’écrit le contenu de "AA" dans la console, alors que j’aimerais juste que l’objet AA soit créé et accessible.

    Je n'ai qu'une pratique occasionnelle de R et aucun bagage en programmation. J'ai parfois u mal à trouver les informations et à comprendre la logique au travers des didacticiels. Si vous avez donc quelques petites conseils à me fournir sur comment construire une fonction de ce genre, je serrai ravie de les lire.

    En vous remerciant d'avance.

  2. #2
    Nouveau membre du Club
    Inscrit en
    Mai 2013
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 18
    Points : 38
    Points
    38
    Par défaut
    Dans ton cas, écrire une fonction n'est pas très pertinent. L'idée de la fonction c'est de lui donner quelque chose en entrées, quelle travaille dessus, et qu'elle te renvoie un résultat. Car oui, théoriquement une fonction renvoie toujours quelque chose : c'est ce que fait le return. Toi, tu lui demandes d'appliquer un script grosso modo ça correspondrait plutôt à un source (voir l'aide R ?source)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    mafunction <- function(A, B){
     
      resultat <- A + B
      return(resultat)
     
    }
    D'accord tu veux faire quelque chose de répétitif, mais ce n'est pas la bonne manière d'opérer. Une alternative intéressante est la fonction lapply() qui peut justement réaliser une opération répétitive sur touts les éléments de quelques chose (d'un vecteur, d'une liste ...). Dans ton cas tu peux imaginer faire un vecteur qui rassemble tous les noms de fichiers et appliquer une fonction qui prendra en entrer un nom de fichier et te renverra un data.frame. Utiliser lapply te permettra d'organiser tes données en une liste de data.frame, chaque élément de la liste étant une série temporelle.

    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
     
     
    mesFichiers <- c("nom1", "nom2", "nomN")
     
    mesDonnees <- lapply(mesFichiers, function(X){
     
       donnees <- read.csv(X, , header=TRUE, sep=";", dec = ".")
       donnees[[1]] <- as.POSIXct(strptime(donnees[[1]], "%d.%m.%Y %H:%M"))
     
       return(donnees)
     
    })
     
    #pour voir la structure/arborescence de la liste :
    str(mesDonnees,1)
    D'accord j'ai une fonction, mais cette fois ci elle m'automatise une tache particulière.

    Bon courage

  3. #3
    Membre expérimenté Avatar de Uranne-jimmy
    Homme Profil pro
    Bioinformatique
    Inscrit en
    Décembre 2012
    Messages
    778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Bioinformatique
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 778
    Points : 1 461
    Points
    1 461
    Par défaut
    Bonjour,
    De ce que je peux savoir, le problème vient de la portée des variables, dans ton cas, AA existe dans la fonction mais pas dans le niveau supérieur. En fait une variable existe dans le niveau de sa création et dans les niveaux inférieurs, mais pas dans les niveaux supérieurs.

    La solution pourrait être de créer AA avant d'appeler la fonction que tu as créé, cette fonction va ensuite lui assigner ce que tu souhaites lui donner, et après tu pourra l'utiliser.

    Après j'ai une expérience limité donc bon tente ^^'
    Expert en recherche google caféinomane

  4. #4
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2011
    Messages : 84
    Points : 51
    Points
    51
    Par défaut
    Merci beaucoup pour ces conseils et informations.
    Cela me semble plus clair et me donne matière à réfléchir sur comment construire mes fonctions à l'avenir ainsi que leur pertinence.

    Pour ce qui est de créer "AA" par exemple, je le comprend bien conceptuellement, mais j'ai du mal à l'écrire concrètement. J'avais d'ailleurs essayé en faisant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    readata <- function(AA,BB) {
    AA <- read.csv("AAAA.csv"
    			, header=TRUE, 
    			, sep=";", dec = ".")
    	AA[[1]] <- as.POSIXct(strptime(AA[[1]], "%d.%m.%Y %H:%M"))
    BB <- read.csv("BBBB.csv"
    			, header=TRUE, 
    			, sep=";", dec = ".")
    	BB[[1]] <- as.POSIXct(strptime(BB[[1]], "%d.%m.%Y %H:%M"))
    }
    mais cela ne fonctionnait toujours pas.

    Si vous avez donc quelques conseils supplémentaires sur comment créer une variable puis lui assigner une valeur en appliquant une fonction, je suis preneuse!!

    Merci

  5. #5
    Membre expérimenté Avatar de Uranne-jimmy
    Homme Profil pro
    Bioinformatique
    Inscrit en
    Décembre 2012
    Messages
    778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Bioinformatique
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 778
    Points : 1 461
    Points
    1 461
    Par défaut
    Si tu fais une fonction, ce n'est pas pour refaire deux fois le même code avec juste "AA" ou "BB" qui change non ? :/
    En partant sur le lapply que collif à montré, pour ton exemple en mettant dans mesFichiers ceci : "AAAA.csv" "BBBB.csv"
    Tu auras une liste mesDonnées qui aura dans une première case l'équivalent de AA et dans une deuxième case l'équivalent de BB.
    Expert en recherche google caféinomane

  6. #6
    Nouveau membre du Club
    Inscrit en
    Mai 2013
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 18
    Points : 38
    Points
    38
    Par défaut
    L'idée c'est de faire une fonction pour qu'à chaque fois qu'elle mange un X elle te retourne un résultat, ton X, c'est chaque fichier.

    On commence 1°) par créer cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    readata <- function(X) {
            donnees <- read.csv(X, header=TRUE, sep=";", dec = ".")
    	donnees [[1]] <- as.POSIXct(strptime(donnees [[1]], "%d.%m.%Y %H:%M"))
            return(donnees)
    }
    2°) On lui prépare les entrées (X) qu'il va manger :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mesFichiers <- c(fichier1='AAAA.csv', fichier1='BBBB.csv)
    Et on applique la fonction a chaque élément de ce vecteur de noms de fichiers (chaque élément du vecteur est utilisé tour à tour)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ?lapply
    mesDonnees <- lapply(mesFichiers, readata)
     
    # et pour rapidement voir la structure de tes données
    ?str
    str(mesDonnees, 1)
    Mais je pense que tu n'a pas bien saisi à quoi servent les fonctions, une petite recherche google m'amène à te proposer le premier lien que je trouve sur les fonctions sous R :
    http://biol09.biol.umontreal.ca/BIO2...rFonctionR.pdf

  7. #7
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2011
    Messages : 84
    Points : 51
    Points
    51
    Par défaut
    Bonjour,

    merci pour l'aide.
    En effet, pour ce cas, une fonction n'est peut-être pas des plus appropriée, mais celà me permet au moins de mieux comprendre grâce à vos conseils.
    Je voulais simplement créer une fonction car j'ai de nombreuses séries de données, qui changent au cours de mon travail, et je voulais simplement pouvoir les lire rapidement sans être obligée d'écrire la fonction "read.csv" à chaque fois et pour chacune d'elles.

    La solution donnée qui consiste à créer la liste qui contiendra tous les data frame: "mes fichiers" est très intéressante. En revanche, comment puis-je à partir de là, créer un data.frame par nom spécifié dans la liste au lieu de faire une seule liste contenant tous mes data.frame.

    Est-ce possible?

    Sinon, j'écrirai la fonction read.csv pour chacune de mes nouvelles séries et sourcerai le script si c'est en effet plus approprié.

    Merci

  8. #8
    Nouveau membre du Club
    Inscrit en
    Mai 2013
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 18
    Points : 38
    Points
    38
    Par défaut
    L'intérêt de la liste est de structurer des objets, ça tombe bien tes données ont besoin de structure.

    Exemple :
    J'ai deux jeux de données avec un temps et une observation y :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    donnees1 <- data.frame(
    	temps = seq(0,10, 0.01),
    	reponse.y = sin(seq(0,10, 0.01))
    )
     
    donnees2 <- data.frame(
    	temps = seq(0,10, 0.01),
    	reponse.y = cos(seq(0,10, 0.01))
    )
     
    plot(reponse.y~ temps, data=donnees1, type='l')
    lines(reponse.y~ temps, data=donnees2, type='l')
    De ces données je crée une liste (dans ton cas c'est ce que tu obtiens après l'éxécution de ta fonction : une liste de jeux de données) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    donnees <- list(
    	monPremierJeuDeDonnees=donnees1,
    	monSecondJeuDeDonnees=donnees2
    )
    Tu peux ensuite appeler chacun des éléments de la liste individuellement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    > head(donnees$monPremierJeuDeDonnees)
      temps   reponse.y
    1  0.00 0.000000000
    2  0.01 0.009999833
    3  0.02 0.019998667
    4  0.03 0.029995500
    5  0.04 0.039989334
    6  0.05 0.049979169
    > class(donnees$monPremierJeuDeDonnees)
    [1] "data.frame"
    Chaque élément de la liste est donc bel et bien un jeu de données, et ça c'est cool, parce que R sait très bien travailler sur ces objets. Admettons que tu veuille un summary de chaque jeu de données, tu pourras l'écrire :

    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
     
    > lapply(donnees, summary)
    $monPremierJeuDeDonnees
         temps        reponse.y      
     Min.   : 0.0   Min.   :-1.0000  
     1st Qu.: 2.5   1st Qu.:-0.3942  
     Median : 5.0   Median : 0.3146  
     Mean   : 5.0   Mean   : 0.1835  
     3rd Qu.: 7.5   3rd Qu.: 0.8104  
     Max.   :10.0   Max.   : 1.0000  
     
    $monSecondJeuDeDonnees
         temps        reponse.y       
     Min.   : 0.0   Min.   :-1.00000  
     1st Qu.: 2.5   1st Qu.:-0.80114  
     Median : 5.0   Median :-0.09587  
     Mean   : 5.0   Mean   :-0.05427  
     3rd Qu.: 7.5   3rd Qu.: 0.67252  
     Max.   :10.0   Max.   : 1.00000
    Mais il ne faut pas oublier qu'une liste est un objet complexe dont la structure peut être visualisé par la fonction str (pour structure bien sûr !)

    Enfin, pour ta première question :
    Je voulais simplement créer une fonction car j'ai de nombreuses séries de données, qui changent au cours de mon travail, et je voulais simplement pouvoir les lire rapidement sans être obligée d'écrire la fonction "read.csv" à chaque fois et pour chacune d'elles.
    Tu ne dois déclarer ta fonction qu'une seule fois dans la session, elle fera partie des objets en mémoire, donc dans ton script tu commence par déclarer ta fonction puis après tu l'appelles quand bon te semble.

  9. #9
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2011
    Messages : 84
    Points : 51
    Points
    51
    Par défaut
    Je comprends l’intérêt de la liste désormais, mais sauf erreur de ma part (ce qui est fort possible), il semblerait que ce ne soit pas exactement adapté à ce que je veux faire.
    Mon but est bien de lire et assigner un nom à chacun de mes data frame, pour pouvoir travailler avec eux individuellement en les nommant. Et de ce que je comprends, si je veux les nommer individuellement, il faut que je les lise individuellement, c’est bien ça ?
    Les mettre dans une liste par la suite reste néanmoins utile puisqu’il m’arrive aussi parfois de travailler avec plusieurs d’entre eux en même temps.

    Mon but initial était de pouvoir écrire une fonction avec des arguments qui lisent certains data frame (ceux avec lesquels j’ai besoin de travailler sur le moment car j’en ai vraiment beaucoup) sous condition T ou F. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Readdata <- fonction(AA=T,BB=F…) {
     
    If (AA == T){ read.csv (« AAAA.csv »,….}
     
    If BB == T){ read.csv (« BBBB.csv »,….}
     
    }
    Or si je veux leur assigner un nom individuellement, donc « AA », « BB », etc. il me faut d’abord les lire un par un, c’est bien ça ? Et dans ce cas écrire un script qui les lise tous et le sourcer serait donc le plus adapté?

Discussions similaires

  1. Trouver une fonction "simple" (reverse engineering)
    Par ®om dans le forum Algorithmes et structures de données
    Réponses: 23
    Dernier message: 28/09/2006, 13h34
  2. prb fonction simple
    Par jacomo dans le forum C
    Réponses: 5
    Dernier message: 26/09/2006, 15h35
  3. [Crypt]Fonction simple de cryptage des données
    Par Agoye dans le forum Sécurité
    Réponses: 5
    Dernier message: 30/08/2006, 19h35
  4. pb execution de fonctions simples
    Par marechal dans le forum Access
    Réponses: 4
    Dernier message: 10/02/2006, 15h51
  5. pb de fonction simple (this.form.submit()..)
    Par petitsims dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 14/01/2005, 09h29

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