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 :

[Rstudio] Affectation de table à Variable dans une boucle FOR


Sujet :

R

  1. #1
    Membre du Club
    Homme Profil pro
    Etudiant - Toulouse
    Inscrit en
    Avril 2017
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Etudiant - Toulouse

    Informations forums :
    Inscription : Avril 2017
    Messages : 57
    Points : 42
    Points
    42
    Par défaut [Rstudio] Affectation de table à Variable dans une boucle FOR
    Bonjour !

    Je suis confronté à un problème aujourd'hui qui m'a l'air pourtant pas bien compliqué à résoudre.
    dans l'idée il me faut créer des tables pour chaque modalités de la colonne "data$colonne"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    table_var1 <- subset(data, data$colonne == "var1")
    table_var2 <- subset(data, data$colonne == "var2")
    table_var3 <- subset(data, data$colonne == "var3")
     
    write.table(table_var1, ...)
    write.table(table_var2, ...)
    write.table(table_var3, ...)
    Ce que je cherche à faire ici et de pouvoir implémenter ce code dans une boucle car il y aura des colonnes avec bien plus de modalités.
    C'est pourquoi j'ai créé ce code qui n'est pas encore fonctionnel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for (i in as.character(unique(data$colonne))){
       i <- subset(data, data$colonne == i)
     }
    Output (réel) = une table nommée i
    Output (voulu) = 3 tables nommées var1, var2, var3,
    Quelqu'un aurait-il des pistes à explorer ?

    En vous remerciant d'avance.
    Mano

  2. #2
    Membre expérimenté
    Inscrit en
    Novembre 2009
    Messages
    703
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 703
    Points : 1 311
    Points
    1 311
    Par défaut Diviser un dataframe en fonction d'une variable
    Bonjour,

    Il ne faut pas raisonner en boucles dans R.

    Une proposition :

    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
    > airquality.month <- split(airquality, airquality$Month)
    > str(airquality.month)
    List of 5
     $ 5:'data.frame':      31 obs. of  6 variables:
      ..$ Ozone  : int [1:31] 41 36 12 18 NA 28 23 19 8 NA ...
      ..$ Solar.R: int [1:31] 190 118 149 313 NA NA 299 99 19 194 ...
      ..$ Wind   : num [1:31] 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
      ..$ Temp   : int [1:31] 67 72 74 62 56 66 65 59 61 69 ...
      ..$ Month  : int [1:31] 5 5 5 5 5 5 5 5 5 5 ...
      ..$ Day    : int [1:31] 1 2 3 4 5 6 7 8 9 10 ...
     $ 6:'data.frame':      30 obs. of  6 variables:
      ..$ Ozone  : int [1:30] NA NA NA NA NA NA 29 NA 71 39 ...
      ..$ Solar.R: int [1:30] 286 287 242 186 220 264 127 273 291 323 ...
      ..$ Wind   : num [1:30] 8.6 9.7 16.1 9.2 8.6 14.3 9.7 6.9 13.8 11.5 ...
      ..$ Temp   : int [1:30] 78 74 67 84 85 79 82 87 90 87 ...
      ..$ Month  : int [1:30] 6 6 6 6 6 6 6 6 6 6 ...
      ..$ Day    : int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
     $ 7:'data.frame':      31 obs. of  6 variables:
      ..$ Ozone  : int [1:31] 135 49 32 NA 64 40 77 97 97 85 ...
      ..$ Solar.R: int [1:31] 269 248 236 101 175 314 276 267 272 175 ...
      ..$ Wind   : num [1:31] 4.1 9.2 9.2 10.9 4.6 10.9 5.1 6.3 5.7 7.4 ...
      ..$ Temp   : int [1:31] 84 85 81 84 83 83 88 92 92 89 ...
      ..$ Month  : int [1:31] 7 7 7 7 7 7 7 7 7 7 ...
      ..$ Day    : int [1:31] 1 2 3 4 5 6 7 8 9 10 ...
     $ 8:'data.frame':      31 obs. of  6 variables:
      ..$ Ozone  : int [1:31] 39 9 16 78 35 66 122 89 110 NA ...
      ..$ Solar.R: int [1:31] 83 24 77 NA NA NA 255 229 207 222 ...
      ..$ Wind   : num [1:31] 6.9 13.8 7.4 6.9 7.4 4.6 4 10.3 8 8.6 ...
      ..$ Temp   : int [1:31] 81 81 82 86 85 87 89 90 90 92 ...
      ..$ Month  : int [1:31] 8 8 8 8 8 8 8 8 8 8 ...
      ..$ Day    : int [1:31] 1 2 3 4 5 6 7 8 9 10 ...
     $ 9:'data.frame':      30 obs. of  6 variables:
      ..$ Ozone  : int [1:30] 96 78 73 91 47 32 20 23 21 24 ...
      ..$ Solar.R: int [1:30] 167 197 183 189 95 92 252 220 230 259 ...
      ..$ Wind   : num [1:30] 6.9 5.1 2.8 4.6 7.4 15.5 10.9 10.3 10.9 9.7 ...
      ..$ Temp   : int [1:30] 91 92 93 93 87 84 80 78 75 73 ...
      ..$ Month  : int [1:30] 9 9 9 9 9 9 9 9 9 9 ...
      ..$ Day    : int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    > head(airquality.month$'5')
      Ozone Solar.R Wind Temp Month Day
    1    41     190  7.4   67     5   1
    2    36     118  8.0   72     5   2
    3    12     149 12.6   74     5   3
    4    18     313 11.5   62     5   4
    5    NA      NA 14.3   56     5   5
    6    28      NA 14.9   66     5   6
    Cordialement,

  3. #3
    Membre du Club
    Homme Profil pro
    Etudiant - Toulouse
    Inscrit en
    Avril 2017
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Etudiant - Toulouse

    Informations forums :
    Inscription : Avril 2017
    Messages : 57
    Points : 42
    Points
    42
    Par défaut
    Alors je viens d'essayer avec le split c'est vraiment mieux que mon subset.

    Cela dit le problème final reste le même. Mettons que je veuille, pour tes données, pouvoir stocker dans des csv les informations de ma table après l'avoir splité par chaque modalités.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    airquality.month <- split(airquality, airquality$Month)
     
    write.table(airquality.month$1,"airquality.month$1.csv", sep = ';' , row.names = FALSE)
    write.table(airquality.month$3,"airquality.month$3.csv", sep = ';' , row.names = FALSE)
    write.table(airquality.month$5,"airquality.month$5.csv", sep = ';' , row.names = FALSE)
    ...
    Y a t-il une possibilité d'automatiser la tâche sous R ?

    Mano

  4. #4
    Membre expérimenté
    Inscrit en
    Novembre 2009
    Messages
    703
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 703
    Points : 1 311
    Points
    1 311
    Par défaut Exporter un dataframe en fonction d'une variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    require(data.table)
    airquality <- airquality # pour pouvoir modifier la table compilée
    setDT(airquality)        # conversion de la table en data.table
    airquality[, write.csv2(.SD, paste0("airquality_month", .BY, ".csv"), row.names = FALSE), by = Month]
    Génère un message Empty data.table (0 rows) of 1 col: Month mais les fichiers semblent bien exportés.

    (Code trouvé ici).

    Cordialement,

  5. #5
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    276
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 276
    Points : 561
    Points
    561
    Par défaut
    Bonjour,

    Il ne faut pas raisonner en boucles dans R.
    C'est une fausse croyance d'autant plus maintenant avec la compilation just in time. Ce qui est vrai c'est que d'imbriquer des boucles n'est pas une bonne idée, et que souvent si les boucles sont longues en terme de temps de calcul c'est parce qu'elles sont mal programmées. Mais ça restera un débat sans fin qui ne dépendra que de ce que l'on veut faire.

    Dans un cas comme celui-ci je pense qu'au contraire la boucle est très pratique et prendra bien moins de temps a programmer à un débutant que d'aller chercher la librairie data.table et de comprendre sa propre logique.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (i in unique(airquality$Month)) 
      write.table(airquality[airquality$Month==i,], file = sprintf("airquality.month%s.txt", i), sep = ';' , row.names = FALSE)
    L'efficacité d'un code se mesure aussi bien au temps qu'il faut pour l’exécuter et qu'au temps nécessaire pour le programmer.

    cdlt

  6. #6
    Membre du Club
    Homme Profil pro
    Etudiant - Toulouse
    Inscrit en
    Avril 2017
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Etudiant - Toulouse

    Informations forums :
    Inscription : Avril 2017
    Messages : 57
    Points : 42
    Points
    42
    Par défaut
    Alors,
    J'ai essayer de voir avec le lien que tu m'a envoyé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    require(data.table)
    airquality <- airquality # pour pouvoir modifier la table compilée
    setDT(airquality)        # conversion de la table en data.table
    airquality[, write.csv2(.SD, paste0("airquality_month", .BY, ".csv"), row.names = FALSE), by = Month]
    Cela génère bien un csv dans mon répertoire sauf qu'il y a toutes les données et elle ne sont pas séparé dans 3 fichier csv distincts.
    J'ai donc opté pour l'autre solution donnée sur le lien précédent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    customFun  = function(DF) {
    write.csv(DF,paste0("mtcars_cyl_",unique(DF$cyl),".csv"))
    return(DF)
    }
     
    mtcars %>% 
    group_by(cyl) %>% 
    do(customFun(.))
    Après avoir chargé les différents packages à savoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    library(dplyr)
    library(readr)
    le message d'erreur suivant apparaît :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    > var %>%
    +   group_by(unique(data$colonne)) %>%
    +   do(customFun(.))
    Error in mutate_impl(.data, dots) : 
      Column `unique(data$colonne)` must be length 32 (the number of rows) or one, not 3
    Je viens donc d'essayer la solution proposé par tototode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for (i in unique(data$colonne)) 
      write.table(data[data$colonne==i,], file = sprintf("...%s.csv", i), sep = ';' , row.names = FALSE)
    Tout mes csv splités par la colonne sont bien créés, c'est la solution qui me semble le plus accessible et la moins "compliqué" à concevoir.
    Merci à vous deux !

    Mano

  7. #7
    Membre expérimenté
    Inscrit en
    Novembre 2009
    Messages
    703
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 703
    Points : 1 311
    Points
    1 311
    Par défaut Exporter un dataframe en fonction d'une variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    require(data.table)
    airquality <- airquality # pour pouvoir modifier la table compilée
    setDT(airquality)        # conversion de la table en data.table
    airquality[, write.csv2(.SD, paste0("airquality_month", .BY, ".csv"), row.names = FALSE), by = Month]
    Cela génère bien un csv dans mon répertoire sauf qu'il y a toutes les données et elle ne sont pas séparé dans 3 fichier csv distincts.
    Bizarre, j'obtiens bien 5 fichiers avec ce code...

    Pour la méthode avec le package dplyr, il faut adapter la fonction à votre table :

    Avec la table mtcars :

    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
    > customFun = function(DF){
    +   write.csv(DF,paste0("mtcars_cyl_",unique(DF$cyl),".csv"))
    +   return(DF)
    + }
    > 
    > library(dplyr)
    > mtcars %>% 
    +   group_by(cyl) %>% 
    +     do(customFun(.))
    # A tibble: 32 x 11
    # Groups:   cyl [3]
         mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
     1  22.8     4 108      93  3.85  2.32  18.6     1     1     4     1
     2  24.4     4 147.     62  3.69  3.19  20       1     0     4     2
     3  22.8     4 141.     95  3.92  3.15  22.9     1     0     4     2
     4  32.4     4  78.7    66  4.08  2.2   19.5     1     1     4     1
     5  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
     6  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
     7  21.5     4 120.     97  3.7   2.46  20.0     1     0     3     1
     8  27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
     9  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
    10  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
    # ... with 22 more rows
    Avec la table airquality :

    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
    > customFun = function(DF){
    +   write.csv(DF,paste0("airquality_month", unique(DF$Month), ".csv"))
    +   return(DF)
    + }
    > 
    > library(dplyr)
    > airquality %>% 
    +   group_by(Month) %>% 
    +     do(customFun(.))
    # A tibble: 153 x 6
    # Groups:   Month [5]
       Ozone Solar.R  Wind  Temp Month   Day
       <int>   <int> <dbl> <int> <int> <int>
     1    41     190   7.4    67     5     1
     2    36     118   8      72     5     2
     3    12     149  12.6    74     5     3
     4    18     313  11.5    62     5     4
     5    NA      NA  14.3    56     5     5
     6    28      NA  14.9    66     5     6
     7    23     299   8.6    65     5     7
     8    19      99  13.8    59     5     8
     9     8      19  20.1    61     5     9
    10    NA     194   8.6    69     5    10
    # ... with 143 more rows
    Ou sans fonction :

    Avec la table mtcars :

    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
    > library(dplyr)
    > library(readr)
    > group_by(mtcars, cyl) %>%
    +   do(write_csv(., paste0(unique(.$cyl), "test.csv")))
    # A tibble: 32 x 11
    # Groups:   cyl [3]
         mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
     1  22.8     4 108      93  3.85  2.32  18.6     1     1     4     1
     2  24.4     4 147.     62  3.69  3.19  20       1     0     4     2
     3  22.8     4 141.     95  3.92  3.15  22.9     1     0     4     2
     4  32.4     4  78.7    66  4.08  2.2   19.5     1     1     4     1
     5  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
     6  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
     7  21.5     4 120.     97  3.7   2.46  20.0     1     0     3     1
     8  27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
     9  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
    10  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
    # ... with 22 more rows
    Avec la table airquality :

    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
    > library(dplyr)
    > library(readr)
    > group_by(airquality, Month) %>%
    +   do(write_csv(., paste0("airquality_month", unique(.$Month), ".csv")))
    # A tibble: 153 x 6
    # Groups:   Month [5]
       Ozone Solar.R  Wind  Temp Month   Day
       <int>   <int> <dbl> <int> <int> <int>
     1    41     190   7.4    67     5     1
     2    36     118   8      72     5     2
     3    12     149  12.6    74     5     3
     4    18     313  11.5    62     5     4
     5    NA      NA  14.3    56     5     5
     6    28      NA  14.9    66     5     6
     7    23     299   8.6    65     5     7
     8    19      99  13.8    59     5     8
     9     8      19  20.1    61     5     9
    10    NA     194   8.6    69     5    10
    # ... with 143 more rows
    Cordialement,

  8. #8
    Membre du Club
    Homme Profil pro
    Etudiant - Toulouse
    Inscrit en
    Avril 2017
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Etudiant - Toulouse

    Informations forums :
    Inscription : Avril 2017
    Messages : 57
    Points : 42
    Points
    42
    Par défaut
    Bonjour,
    Exact j'ai fais une erreur sur l'orthographe de ma variable
    Les deux solutions fonctionnent parfaitement merci.

    Mano

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 10/01/2013, 11h07
  2. table variable dans une boucle for
    Par ludo99 dans le forum PL/SQL
    Réponses: 5
    Dernier message: 03/12/2009, 17h25
  3. Appeler une série de variable dans une boucle for
    Par jujuf1 dans le forum MATLAB
    Réponses: 2
    Dernier message: 19/02/2008, 16h06
  4. Portée d'une variable dans une boucle FOR ?
    Par Neo41 dans le forum C++
    Réponses: 20
    Dernier message: 17/11/2006, 11h14
  5. [VB.net] Declaration variable dans une boucle for
    Par nico10gbb dans le forum Windows Forms
    Réponses: 4
    Dernier message: 10/05/2006, 11h45

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