Import de fichier txt sans les métadonnées

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Elise Lacoste
Messages : 33
Enregistré le : 02 Juin 2009, 15:49

Import de fichier txt sans les métadonnées

Messagepar Elise Lacoste » 27 Jan 2023, 09:23

Bonjour,

Je bloque sur l'import de plusieurs fichiers .txt qui contiennent des métadonnées.
Chaque fichier comporte un nombre de lignes de métadonnées différent, donc pas possible d'utiliser "skip". Le nombre de colonnes de chaque fichier est également différent, et il y a des tabulations dans les métadonnées (j'ai exploré plusieurs pistes...).
Le seul point commun entre mes fichiers est que les 2 premières colonnes des données que je veux extraire sont "Date" et "Time". Je pencherai donc pour trouver une expression régulière qui permette de lire mes tableaux à partir de ces 2 colonnes? mais je ne maitrise pas du tout...
Ci-dessous l'exemple d'un fichier importé avec "readLines". Dans cet exemple les données qui m'intéressent commencent à la ligne 31.

Merci si vous avez l'astuce!


[2] "!---------------------------------!"
[3] "! METADATA !"
[4] "!---------------------------------!"
[5] "Site :
[6] "Station : AC_ZM_LOW"
[7] "Longitude : -1.18917"
[8] "Latitude : 44.67741"
[9] "XYRef : WGS84"
[10] "Z0Ref : Cote Marine"
[11] "Z0CM : nan"
[12] "Intertidal : False"
[13] "TimeRef : UTC+1"
[14] "Date_Start : 2020/02/04 17:40:00"
[15] "Date_End : 2021/05/05 10:14:05"
[16] "NbData : 49817"
[20] "!---------------------------------!"
[21] "! VARIABLES !"
[22] "!---------------------------------!"
[23] "Date\t\tyyyy/mm/dd\t\tDate of record"
[24] "Time\t\tHH:MM:SS.MS\t\tTime of record"
[25] "TempWat\t\tCelsius degree\t\tWater temperature recored by the UA T/L sensor."
[26] "LightWat\t\tlumens.m-2\t\tLight in water recorded by the UA T/L sensor."
[27] "SN_UA\t\tNone\t\tSerial number of the UA T/L sensor."
[28] "!---------------------------------!"
[29] "! DATA !"
[30] "!---------------------------------!"
[31] "Date\tTime\tTempWat\tLightWat\tSN_UA"
[32] "2020/02/04\t17:40:00.000000\t12.401\t366.0\t20518692"
[33] "2020/02/04\t17:50:00.000000\t12.304\t204.5\t20518692"
[34] "2020/02/04\t18:00:00.000000\t12.401\t139.9\t20518692"

Fred Santos
Messages : 233
Enregistré le : 11 Avr 2009, 10:00
Contact :

Re: Import de fichier txt sans les métadonnées

Messagepar Fred Santos » 27 Jan 2023, 09:38

Bonjour Elise,

Une piste possible :

1. Lire le fichier complet avec la fonction readLines().
2. Repérer, à l'aide d'une expression régulière (par exemple avec grep()), la première ligne contenant les données qui vous intéressent.
3. Ensuite, il est possible de remettre en forme (plus ou moins douloureusement) l'ensemble des lignes suivantes sous la forme d'une matrice, par exemple avec un strsplit() séparant les colonnes à chaque tabulation.

Un exemple ici : https://gitlab.com/f-santos/anthrostat/ ... GM_files.R
(Il s'agit d'une fonction que j'avais codée pour importer des fichiers présentant des contraintes similaires aux vôtres. Elle n'était destinée qu'à des fichiers contenant très peu de lignes et n'est donc pas codée pour être efficace sur de gros volumes de données, mais ça s'adapte sans trop de soucis.)

Je pourrai tenter de me pencher un peu plus là-dessus si besoin.

F.

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Import de fichier txt sans les métadonnées

Messagepar Logez Maxime » 27 Jan 2023, 10:10

Bonjour,

tu peux essayer ça :

Code : Tout sélectionner

f <- function (n)
rep(c("character", "NULL"), c(2, n - 2))

fun <- function (file)
{
    l1 <- readLines(file)
    n1 <- grep("^Date\tTime", l1)
    nc <- length(unlist(strsplit(l1[n1 + 1], "\t")))
    l1 <- read.table(file, skip = n1 - 1, sep = "\t", h = T, colClasses = f(nc))
    l1
}

fun("mon fichier.txt")
Cordialement,
Maxime

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Import de fichier txt sans les métadonnées

Messagepar Maxime Deniaux » 27 Jan 2023, 10:55

Déjà 2 réponses !

Je donne aussi une idée de ce sur quoi je serais parti

Première étape, j'aurais cherché à quelle ligne (avec une boucle) il y a ce qui t'intéresse ("Date\t"). (cf. le 2eme point de Fred Santos)
Je garde toutes les lignes d'après, y compris celle ci. Ou je vire celles d'avant, peu importe.

Deuxième étape, je remplace avec un gsub() tous les séparateurs "\t" avec :

Code : Tout sélectionner

for(i in 1:nrow(dataframe)){
                                           dataframe[i,] = gsub("\\\\t",";",dataframe[i,])
                                         }


(suis nul en expressions régulière donc peut-être c'est mal écrit, faut demander à Maxime Logez :p, mais visiblement ça a fonctionné...)

Ensuite, je place la première ligne en nom de colonne et j'enlève la première ligne qui ne sert plus.

Code : Tout sélectionner

colnames(dataframe) = dataframe[1,]
dataframe %>% slice(-1)


Puis j'exporte ce dataframe avec :

Code : Tout sélectionner

write.table(dataframe, file = "chemin/dataframe.txt", row.names = F, dec = ".", quote = FALSE)


Et je le réimporte...

Code : Tout sélectionner

dataframe_corrige <- read_delim("chemin/dataframe.txt",
           delim = ";", escape_double = FALSE, trim_ws = TRUE)


Et normalement, chaque colonne est bien séparée désormais

(J'ai testé avec une partie très réduite de ton exemple, cad les lignes 31 à 34. Je n'ai pas fait la première partie en cherchant avec une boucle quelle est la ligne où il y a "Date\t")

Bonne journée

Elise Lacoste
Messages : 33
Enregistré le : 02 Juin 2009, 15:49

Re: Import de fichier txt sans les métadonnées

Messagepar Elise Lacoste » 27 Jan 2023, 12:03

Whaou, merci pour votre vitesse de réaction!
Ça fonctionne parfaitement avec le code de Maxime, j'ai toutefois supprimé l'argument "nc" qui faisait que seules les 2 premières colonnes étaient lues.
Si ça peut servir à d'autres, j'ai intégré une colonne avec l'identifiant de mon fichier extrait des métadonnées (id1), puis j'ai utilisé la fonction dans une autre fonction pour lire plusieurs fichiers et les réunir dans un seul data.frame.

Code : Tout sélectionner

fun <- function (file)
  {
    l1 <- readLines(file)
    id1 <- l1[1]
    n1 <- grep("^Date\tTime", l1)
 #  nc <- length(unlist(strsplit(l1[n1 + 1], "\t")))
    l1 <- read.table(file, skip = n1 - 1, sep = "\t", h = T)
    l1$id=id1
    l1
  }
 
  multmerge <- function(mypath = getwd()) {
    dataset <- list.files(path=mypath, full.names=TRUE, pattern=".txt") %>%
      lapply(fun) %>%
      bind_rows()
    dataset
  }
  mydata <-  multmerge(mypath)
 


Merci encore,
Bonne journée!


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité