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 :

Modifier un data.frame par une fonction


Sujet :

R

  1. #1
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 556
    Par défaut Modifier un data.frame par une fonction
    Bonjour,
    Voilà, j'ai un truc tout bête, j'essaie de modifier un data.frame avec une fonction ; et ça ne marche pas.
    Voici mon code tout simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    BDD <- data.frame(A=c(1,2,3),B=c('a','b','c'),C=c(23,NA,111))
    print(BDD)
    Fonction <- function() {  BDD$C[is.na(BDD$C)] = 0 }
    Fonction()
    print(BDD)
    Mon data.frame n'a pas bougé, alors que par rapport à la fonction, le data.frame est bien un élément extérieur, mais qui fait partie de son environnement.
    Je sèche !

    Est-ce que quelqu'un aurait une idée ?

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 492
    Par défaut
    salut enicnath,
    un coup de mou
    il faut penser au retour de la fonction et à la réaffectation dans ton dataframe initial

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    BDD <- data.frame(A=c(1,2,3),B=c('a','b','c'),C=c(23,NA,111))
    print(BDD)
    Fonction <- function() {  
      BDD$C[is.na(BDD$C)] = 0
      return(BDD)}
    BDD <- Fonction()
    print(BDD)
    bonne journée

  3. #3
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 556
    Par défaut
    Citation Envoyé par xavier-Pierre Voir le message
    salut enicnath,
    un coup de mou
    il faut penser au retour de la fonction et à la réaffectation dans ton dataframe initial
    ...
    Merci Xavier-Pierre, mais c'est une solution que je voulais éviter, parce qu'en réalité, mon souci concerne une table de plusieurs milliers de lignes.
    Et c'est une table que j'attaque dans une boucle, qui elle-même est longue et compliquée.
    Du coup, j'ai une boucle avec réaffectation de la table ; et c'est très consommateur de temps.
    En R de plus, il ne semble pas qu'on puisse passer une référence à un objet dans une fonction, comme l'indique ce lien

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 492
    Par défaut
    bonjour,
    regarde le package data.table
    cdlt

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 492
    Par défaut
    le code de l'exemple modifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    library(data.table)
    BDD <- data.table(A=c(1,2,3),B=c('a','b','c'),C=c(23,NA,111))
    print(BDD)
    Fonction <- function() {  BDD[is.na(C),C :=0] }
    Fonction()
    print(BDD)

  6. #6
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 556
    Par défaut
    Citation Envoyé par xavier-Pierre Voir le message
    bonjour,
    regarde le package data.table
    cdlt
    Ah ouais ... bien !
    Merci

  7. #7
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 556
    Par défaut
    En fait, toujours sur un data.frame, on peut utiliser l'opérateur <<- pour signifier dans une fonction que l'objet à gauche de l'opérateur est une variable globale.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    DF <- data.frame(A=c('11','22','33','44','55'), B=c(123,456,78,9,0))
    Fonction <- function(Obs,Var,Valeur) { 
       DF[[Var]][Obs] <<- Valeur
    }
    Fonction(1,2,3)
    Dans cet exemple, on a modifié la deuxième variable de la première observation, en remplaçant 123 par la valeur 3 !

  8. #8
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 492
    Par défaut
    Bonjour enicnath, oui cela fonctionne mais ta fonction utilise une copie de ton dataframe pour le changement de valeur alors qu'avec le package data.table le changement se fait sur directement sur le dataframe

    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
     
    ## taille du jeu de données
    n <- 1e6
     
    ## dataframe
    DF <- data.frame(
      A = sample(1:100, n, TRUE),
      B = sample(1:100, n, TRUE)
    )
     
    ## data.table
    DT <- as.data.table(DF)
     
    ### ta fonction
    Fonction <- function(Obs,Var,Valeur) { 
      DF[[Var]][Obs] <<- Valeur
    }
    ## test de ta fonction
    tracemem(DF)  ##permet de voir si le dataframe est copié
     
    Fonction(1,2,999)
     
    ## test solution data.table
     
    tracemem(DT)
     
    DT[1, B := 999]
     
     
    ## comparaison vitesse
    ## nombre de changements
    n_iter <- 10000
     
    untracemem(DF) ## pour supprimer le suivi des copies et 
    ## ne pas ralentir le traitement avec ta fonction
     
    # ta fonction
    t1 <- system.time({
      for(i in 1:n_iter){
        Fonction(1,2,i)
      }
    })
     
    # data.table
    t2 <- system.time({
      for(i in 1:n_iter){
        DT[1, B := i]
      }
    })
     
    print(t1)
    print(t2)
     
    ##chez moi j'ai :
     
    # > print(t1)
    # utilisateur     système      écoulé 
    # 26.81       16.23       43.70 
    # 
    # > print(t2)
    # utilisateur     système      écoulé 
    # 5.01        0.26        5.40
    autrement j'attendais tranquillement le 14 mars pour commémorer la "mort" du forum R, mais il y a encore un petit soubresaut d'activité;
    bonne journée

  9. #9
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 556
    Par défaut
    Citation Envoyé par xavier-Pierre Voir le message
    ... autrement j'attendais tranquillement le 14 mars pour commémorer la "mort" du forum R, mais il y a encore un petit soubresaut d'activité;
    bonne journée
    C'est vrai qu'il n'est plus très actif.
    N'y aurait-t'il plus aucun besoin sur R ?

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

Discussions similaires

  1. [Python 3.X] débutant - Valeur de l'argument modifié par une fonction
    Par awawawa dans le forum Général Python
    Réponses: 4
    Dernier message: 14/01/2022, 11h45
  2. Réponses: 2
    Dernier message: 05/07/2019, 08h16
  3. Réponses: 11
    Dernier message: 31/10/2005, 17h59
  4. [LG]résultat renvoyé par une fonction
    Par le 27 dans le forum Langage
    Réponses: 3
    Dernier message: 10/12/2003, 10h31
  5. tableau javascript ecrit par une fonction asp
    Par LineLe dans le forum ASP
    Réponses: 4
    Dernier message: 03/11/2003, 08h38

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