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 :

Manipulation de plusieurs fichiers, écriture et calculs dans R


Sujet :

R

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 80
    Points : 34
    Points
    34
    Par défaut Manipulation de plusieurs fichiers, écriture et calculs dans R
    Bonjour,
    J’aimerais créer un script pour lire et faire des combinaisons de plusieurs fichiers xls en un seul csv final, puis ajouter des données à partir d’un autre fichier et enfin faire des calculs. Voici les explications pas à pas de ce que j’aimerais faire avec des fichiers exemples, est-ce que quelqu’un pourrait m’aider svp ?
    Un grand merci par avance ,
    M.

    Étapes (tous les fichiers mentionnés dessous sont joints à mon message):
    1- J’ai plusieurs fichiers de base construits de la manière suivante : un fichier par année et par lieu, les fichiers sont nommés comme ceci : especeAnnee_Cplieu_NomEssai_typeEssai
    Donc pour les 4 fichiers de base exemples ici ça donne par exemple : « cm2019_1250_20_type1 », « cm2019_1600_20_type1 », « cm2020_1250_20_type1 », « cm2020_1600_20_type1 ».

    Dans chacun des 4 fichiers il y a pour une année et un lieu donné : 2 variétés et 3 réplicats et la donnée mesurée qui est le rendement.
    On a en plus l’info d’une station correspondante et les colonnes dates de plantation et dates de récolte.

    La première chose que je veux faire c’est réunir ces 4 fichiers en un seul sur base des entêtes comme dans le fichier final exemple « setFinal ».

    2- Ensuite j’aimerais dans le fichier « setFinal » modifier des infos dans la colonne « station », càd : pour le lieu « Cplieu» = 1250 on a station = stn1 et j’aimerais remplacer par stn3 ; puis pour le lieu Cplieu = 1600 on à stn 2 et j’aimerais remplacer par stn 4.
    Puis j’aimerais ajouter des colonnes à partir d’un autre fichier « date2 » dans ce fichier « setFinal » ; j’aimerais récupérer les 3 colonnes du fichier date2 «datePlantation2 », « dateRecolte2 » et « infoEssai » et les ajouter dans setFinal pour les lignes qui ont la même année « annee » et le meme lieu « lieuID » entre les 2 fichiers « date2 » et « setFinal »
    Ça donne le fichier exemple « setFinal2 »

    3- Enfin ; j’aimerais dans le fichier « setFinal 2 », pour les colonnes « datePlantation2 » et « dateRecolte2 » si il y a « NA » dans les 2, alors calculer une date moyenne et la remplacer dans la case pour chacune des 2 colonnes basée sur la moyenne de « datePlantation2 » et « dateRecolte2 » du reste du fichier pour lesquelles on a des données.
    Ça donne « setFinal3 ».
    cm2020_1250_20_type1.xlsx cm2019_1600_20_type1.xlsx cm2019_1250_20_type1.xlsx cm2020_1600_20_type1.xlsx dates2.xlsx setFinal.xlsxsetFinal2.xlsx setFinal3.xlsx

  2. #2
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Bonjour.

    Sur quels points bloques-tu exactement ? A quoi ressemble ton script à l'heure actuelle ?
    Bon courage.
    Olivier

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 80
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par olivier.decourt Voir le message
    Bonjour.

    Sur quels points bloques-tu exactement ? A quoi ressemble ton script à l'heure actuelle ?
    merci pour le retour.

    Pour le moment je n'ai pas réussi à beaucoup avancer, je suis bloquée à la première étape, lors de la fusion des fichiers j'ai un message d'erreur (voir dessous) et j'ai des NA qui sont introduits dans mon fichier.

    J'aimerais aussi automatiser la lecture de tous les fichiers dans mon dossier et automatiser le "rbind", voir mon script ci-dessous, car ici c'est un exemple mais en réalité j'ai plus de 300 fichiers (qui auront tous la même entête). Auriez-vous une idée de code pour faire ça et aussi les étapes suivantes indiquées dans mon premier message svp?

    merci par avance pour votre aide.

    Warning messages:
    1: In `[<-.factor`(`*tmp*`, ri, value = c(15, 15, 15, 15, 15, 15)) :
    niveau de facteur incorrect, NAs générés
    2: In `[<-.factor`(`*tmp*`, ri, value = c(96, 47, NA, 80, 40, 160)) :
    niveau de facteur incorrect, NAs générés
    3: In `[<-.factor`(`*tmp*`, ri, value = c(96, 74, 85, 52, 41, 56)) :
    niveau de facteur incorrect, NAs générés
    4: In `[<-.factor`(`*tmp*`, ri, value = c(15, 15, 15, 15, 15, 15)) :
    niveau de facteur incorrect, NAs générés
    5: In `[<-.factor`(`*tmp*`, ri, value = c(85, 190, 25, 40, 78, 60)) :
    niveau de facteur incorrect, NAs générés
    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
    setwd ("F:\\Rfiles")
     
    fi1<-read.csv2("cm2019_1250_20_type1.csv", na.strings = "NA",header = TRUE)
    fi2<-read.csv2("cm2019_1600_20_type1.csv", na.strings = "NA",header = TRUE)
    fi3<-read.csv2("cm2020_1250_20_type1.csv", na.strings = "NA",header = TRUE)
    fi4<-read.csv2("cm2020_1600_20_type1.csv", na.strings = "NA",header = TRUE) 
                #comment lire tous les fichiers d'un dossier? car en realité j'ai > 300 fichiers
     
    str(fi1)
    head(fi1)
    head(fi2)
    head(fi3)
    head(fi4)
     
    for (i in 11:ncol(fi1)) {
      fi1[, i] <- as.numeric(as.character(fi[, i]))
    }
    for (i in 11:ncol(fi2)) {
      fi2[, i] <- as.numeric(as.character(fi2[, i]))
    }
    for (i in 11:ncol(fi3)) {
      fi3[, i] <- as.numeric(as.character(fi3[, i]))
    }
    for (i in 11:ncol(fi4)) {
      fi4[, i] <- as.numeric(as.character(fi4[, i]))
    }
     
     
    fi5<-rbind(fi1,fi2,fi3,fi4) #comment automatiser ce "rbind? car en realité j'ai > 300 fichiers
    head(fi5)
                #ici problème génère des NAs sur certains chiffres
     
    write.table(fi5, file="setFinal.csv")

  4. #4
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Ce qu'on peut essayer tout de suite, c'est de travailler sur les 300 et quelques fichiers, peu importe leur nombre.
    On peut lister les fichiers d'un répertoire avec la fonction list.files, avec une précision dans l'option pattern pour se limiter à certains noms / types de fichiers.

    On pourrait ensuite monter une boucle parcourant chacun des noms renvoyés par list.files, mais on aurait encore ensuite à empiler tous les data.frames importés ainsi. Le package {purrr} va permettre de faire tout ça d'un coup, boucle et empilement, en une seule fonction map_df.
    La syntaxe est : map_df(énumération de fichiers, fonction d'import, options de la fonction d'import).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    setFinal <- map_df(list.files(pattern=".csv"),
       read.csv2,
       na.strings = "NA",
       header = TRUE,
       stringsAsFactors=FALSE)
    Tu peux éventuellement encore ajouter une option colClasses à ton import pour contrôler les types des colonnes, si nécessaire.
    Bon courage.
    Olivier

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 80
    Points : 34
    Points
    34
    Par défaut
    Si cela vous convient, je préférait commencer avec l'exemple (les 4 csv en PJ) mais en gardant à l'idée que j'aurai beaucoup de fichiers (car je n'ai pas encore tous les fichiers, et je dois encore travailler sur mes fichiers de base avant de les utiliser, comme je ne suis pas très douée, je voulais anticiper).

    j'ai mis les 4 csv dans un dossier "all" et j'ai testé le code que vous proposez, j'ai un ,message d'erreur (voir dessous)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    setwd ("F:\\Rfiles\\all")
    install.packages("purrr")
    library("purrr")
    setFinal <- map_df(list.files(pattern=".csv"),
                       read.csv2,
                       na.strings = "NA",
                       header = TRUE,
                       stringsAsFactors=FALSE)
    Error: Can't combine `..1$surface` <character> and `..2$surface` <integer>.
    Run `rlang::last_error()` to see where the error occurred.
    > setFinal <- map_df(list.files(pattern=".csv"),
    +                    read.csv2,
    +                    na.strings = "NA",
    +                    header = TRUE,
    +                    stringsAsFactors=FALSE)
    Error: Can't combine `..1$surface` <character> and `..2$surface` <integer>.
    Run `rlang::last_error()` to see where the error occurred.
    > rlang::last_error()
    <error/vctrs_error_incompatible_type>
    Can't combine `..1$surface` <character> and `..2$surface` <integer>.
    Backtrace:
     1. purrr::map_df(...)
     2. dplyr::bind_rows(res, .id = .id)
     3. vctrs::vec_rbind(!!!dots, .names_to = .id)
     5. vctrs::vec_default_ptype2(...)
     6. vctrs::stop_incompatible_type(...)
     7. vctrs:::stop_incompatible(...)
     8. vctrs:::stop_vctrs(...)
    par contre si je tape juste la fonction list.files ça fonctionne bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    > list.files(pattern=".csv")
    [1] "cm2019_1250_20_type1.csv" "cm2019_1600_20_type1.csv" "cm2020_1250_20_type1.csv"
    [4] "cm2020_1600_20_type1.csv"

  6. #6
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Bonjour.
    Comme le dit le message d'erreur, il y a un problème de cohérence de type pour la colonne "surface" dans les différents fichiers : elle est en texte dans le 1er fichier et numérique (entière) dans le 2e.
    Est-ce qu'il comprend correctement le séparateur décimal ? Les valeurs manquantes ?

    Essayez d'importer séparément les deux premiers CSV et comparez le type des colonnes. Ça devrait vous aider à trouver quelles options ajouter à la fonction d'import pour que ça fonctionne bien.
    Bon courage.
    Olivier

  7. #7
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 80
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par olivier.decourt Voir le message
    Bonjour.
    Comme le dit le message d'erreur, il y a un problème de cohérence de type pour la colonne "surface" dans les différents fichiers : elle est en texte dans le 1er fichier et numérique (entière) dans le 2e.
    Est-ce qu'il comprend correctement le séparateur décimal ? Les valeurs manquantes ?

    Essayez d'importer séparément les deux premiers CSV et comparez le type des colonnes. Ça devrait vous aider à trouver quelles options ajouter à la fonction d'import pour que ça fonctionne bien.
    merci, j'ai remplacé les "." par des virgules dans mes fichier de départ et maintenant ça fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    setFinal <- map_df(list.files(pattern=".csv"),
                       read.csv2,
                       na.strings = "NA",
                       header = TRUE,
                       stringsAsFactors=FALSE) 
     
    head(setFinal)
    j'obtiens ceci:
      espece annee  lieu lieuID numeroEssai typeEssai station variete replicate Cplieu surface
    1     cm  2019 lieu1     L1          20     type1    stn1    var1         1   1250    10.5
    2     cm  2019 lieu1     L1          20     type1    stn1    var1         2   1250    10.5
    3     cm  2019 lieu1     L1          20     type1    stn1    var1         3   1250    10.5
    4     cm  2019 lieu1     L1          20     type1    stn1    var2         1   1250    10.5
    5     cm  2019 lieu1     L1          20     type1    stn1    var2         2   1250    10.5
    6     cm  2019 lieu1     L1          20     type1    stn1    var2         3   1250    10.5
      rendement datePlantation dateRecolte
    1      83.0          43568       43718
    2      70.2          43568       43718
    3      67.2          43568       43718
    4      90.0          43568       43718
    5     100.0          43568       43718
    6     150.0          43568       43718
    par contre si je veux partir de fichier .xls (mes fichiers de base sont en .xls pour le moment), ça ne fonctionne plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    setwd ("D:\\Rfiles\\xls\\all")
    #install.packages("purrr")
    library("purrr")
     
     
    setFinal2 <- map_df(list.files(pattern=".xls"),
                       read.csv2,
                       na.strings = "NA",
                       header = TRUE,
                       stringsAsFactors=FALSE)
    j'ai le message d'erreur dessous mais pourtant c'est exactement les mêmes fichiers mais en xls, est-ce possible de convertir tous les fichiers en csv au début du code?
    merci par avance

    Warning messages:
    1: In read.table(file = file, header = header, sep = sep, quote = quote, :
    line 1 appears to contain embedded nulls
    2: In read.table(file = file, header = header, sep = sep, quote = quote, :
    incomplete final line found by readTableHeader on 'cm2019_1250_20_type1.xlsx'
    3: In read.table(file = file, header = header, sep = sep, quote = quote, :
    line 1 appears to contain embedded nulls
    4: In read.table(file = file, header = header, sep = sep, quote = quote, :
    incomplete final line found by readTableHeader on 'cm2019_1600_20_type1.xlsx'
    5: In read.table(file = file, header = header, sep = sep, quote = quote, :
    line 1 appears to contain embedded nulls
    6: In read.table(file = file, header = header, sep = sep, quote = quote, :
    incomplete final line found by readTableHeader on 'cm2020_1250_20_type1.xlsx'
    7: In read.table(file = file, header = header, sep = sep, quote = quote, :
    line 1 appears to contain embedded nulls
    8: In read.table(file = file, header = header, sep = sep, quote = quote, :
    incomplete final line found by readTableHeader on 'cm2020_1600_20_type1.xlsx'
    > head(setFinal2)
    [1] PK...
    <0 lignes> (ou 'row.names' de longueur nulle)

  8. #8
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    1) Plutôt que de modifier vos fichiers lus (pensez quand vous en aurez 300 !), utilisez une option comme dec dans read.csv2.
    2) Non, effectivement on ne peut pas utiliser read.csv2 sur des fichiers Excel. Vous pouvez utiliser read_excel du package {readxl} par exemple. Attention les options ne sont pas tout à fait les mêmes que dans read.csv2.
    Bon courage.
    Olivier

  9. #9
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 80
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par olivier.decourt Voir le message
    1) Plutôt que de modifier vos fichiers lus (pensez quand vous en aurez 300 !), utilisez une option comme dec dans read.csv2.
    2) Non, effectivement on ne peut pas utiliser read.csv2 sur des fichiers Excel. Vous pouvez utiliser read_excel du package {readxl} par exemple. Attention les options ne sont pas tout à fait les mêmes que dans read.csv2.
    ok merci oui vous avez raison, je vais travailler avec un option.

    j'ai testé la lecture xls mais j'ai des soucis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    setwd ("D:\\Rfiles\\xls\\all")
    library(readxl)
    #install.packages("purrr")
    library("purrr")
     
    setFinal2 <- map_df(list.files(pattern=".xls"),
                        read_excel,
                        1,
                        col_names = TRUE,
                        na = c("?", "/", " ", "-")) 
    head(setFinal2)
    Error: Column `rendement` can't be converted from numeric to character
    > head(setFinal2)
    [1] PK...
    <0 lignes> (ou 'row.names' de longueur nulle)

    je pense que je vais convertir mes fichiers en csv ça sera plus simple.

    donc une fois que j'ai fait ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    setFinal <- map_df(list.files(pattern=".csv"),
                       read.csv2,
                       na.strings = "NA",
                       header = TRUE,
                       stringsAsFactors=FALSE) 
     
    head(setFinal)
    comment je fais pour les étapes suivantes 2 et 3 dessous svp?

    2- Ensuite j’aimerais dans le fichier « setFinal » modifier des infos dans la colonne « station », càd : pour le lieu « Cplieu» = 1250 on a station = stn1 et j’aimerais remplacer par stn3 ; puis pour le lieu Cplieu = 1600 on à stn 2 et j’aimerais remplacer par stn 4.
    Puis j’aimerais ajouter des colonnes à partir d’un autre fichier « date2 » dans ce fichier « setFinal » ; j’aimerais récupérer les 3 colonnes du fichier date2 «datePlantation2 », « dateRecolte2 » et « infoEssai » et les ajouter dans setFinal pour les lignes qui ont la même année « annee » et le meme lieu « lieuID » entre les 2 fichiers « date2 » et « setFinal »
    Ça donne le fichier exemple « setFinal2 »

    3- Enfin ; j’aimerais dans le fichier « setFinal 2 », pour les colonnes « datePlantation2 » et « dateRecolte2 » si il y a « NA » dans les 2, alors calculer une date moyenne et la remplacer dans la case pour chacune des 2 colonnes basée sur la moyenne de « datePlantation2 » et « dateRecolte2 » du reste du fichier pour lesquelles on a des données. Aussi je ne sais pas si cela est possible mais pour les dates qui auront été calculées, j'aimerais ajouter une colonne à côté qui donne la plausibilité donc si c'est une donnée calculée qui dit "estimated" et si c'est une donnée d'origine qui dit "origine"

    Ça donne « setFinal3 » (avec en plus la colonne plausibilité du coup).

    merci par avance

Discussions similaires

  1. Réponses: 28
    Dernier message: 05/09/2019, 09h44
  2. Réponses: 38
    Dernier message: 26/09/2008, 17h46
  3. Macro VBA - Manipulation de plusieurs fichiers
    Par Shaia79 dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 27/02/2008, 21h06
  4. Réponses: 0
    Dernier message: 09/10/2007, 23h19
  5. Réponses: 0
    Dernier message: 09/10/2007, 17h51

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