Définir son répertoire de travail (dossier dans lequel se trouve les données brutes).

rm(list=ls(all=TRUE))
graphics.off()
repDonnees="~/Protocole_uHMM/MAREL-Carnot"
Le symbole "~" correspond au système d'exploitation sous linux. Pour un système d'exploitation sous windows, il sera de type "C:\Program Files\dossier_du_programme\".

Le fichier concerné (se situant dans le répertoire de travail) va être importer. Pour cela, le vecteur nommé "data" correspond au dossier qui contient les données brutes. Puis la deuxième ligne de code correspond aux données brutes qui seront exploitées. Ce dossier est reconnu grâce à l'argument "pattern" qui est égal à une partie (=c) du nom du dossier souhaité.

La lecture du fichier sous R est effectué. Dans notre cas le séparateur est une virgule et la décimale et un point, qu'il faudra préciser. L'argument "header", demande si les données possédent les noms des paramètres en première ligne. Nous l'appelons df.

data=list.files(path=repDonnees)
files.csv=list.files(path=repDonnees, full.names=TRUE, pattern=c("2216.csv"))
df=read.csv(files.csv, header=TRUE, sep=",", dec=".")

Conservation d'une partie des données.

nCol=ncol(df)
nLig=nrow(df)
N=ceiling(0.01*nLig); # prends 1% des données, à moduler selon le nombre de données et l'alignement souhaité.
df=df[1:N,] # données allant de la 1ère valeur à N (1% des données totales).

Alignements

Seule la colonne contenant la date sera extraite. L'indice de la colonne date est alors repéré, "names(df)" donne les noms de toutes les colonnes de df. L'argument pattern doit être égal au nom exacte de la colonne de df.

names(df) # Visualisation des noms de toutes les colonnes de df.
idate=grep(pattern="DATE..yyyy.mm.ddThh.mi.ssZ", names(df),ignore.case=T); idate
La colonne date se situe à la 2ème ligne.

L'extraction de cette colonne est alors réalisée.

date=as.character((df)[,idate]); head(date)

Puis, elle est mise sous le format POSIXt (AAAA-MM-JJ hh:mm:ss). L'argument "format" reprend exactement le format initial de la colonne date.
%Y correspond aux années
%m correspond au mois
%d correpond au jour
%H correspond à l'heure
%M correspond aux minutes
%S correspond aux secondes

df$temps=strptime(date, format="%Y-%m-%dT%H:%M:%SZ"); head(df$temps)

Rendre régulière la série: Plusieurs exemples illustrés. \((1 mois, 1 semaine, 1 journée, 1 heure, 30 minutes ,20 minutes, 10 minutes)\)

1 mois

Extraction de la date (grâce aux "%F" qui correspond AAAA-MM-JJ) dans un vecteur nommé date. Et extraction du mois de chaque acquisition dans un autre vecteur nommé mois.

date=format(df$temps,"%F"); head(date)
mois=as.numeric(format(df$temps,"%m")); head(mois)

Nous considérons le moment de l'acquisition égale au 15 ème jour de chaque mois, il est ensuite mis sous format POSIXt.

df$temps=strptime(format(df$temps, "%Y-%m-15"),format="%Y-%m-%d"); head(df$temps)

La création de la séquence "a", qui va de la date la plus ancienne à la plus récente. De plus, la fréquence est insérer par l'argument "by".

min.date=min(df$temps,na.rm=T); min.date
max.date=max(df$temps,na.rm=T); max.date
a=seq(min.date,max.date,by="1 month"); head(a); tail(a)

Création du tableau, en y incluant seulement le vecteur "a".

df2=data.frame(temps=as.POSIXct(a)); df2[1:3,]

Fusion du tableau avec le tableau de donnée brute initial (df1).

df1=merge(df,df2, all=TRUE); df1[1:7,1:3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et on ne garde que la valeur maximum des doublons créés.

df1.M=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
                FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
                {out=max(x,na.rm=T);}; out}); df1.M[1:7,1:5]

Suppressions des données inutiles pour la suite.

rm(date); rm(mois); rm(min.date); rm(max.date); rm(a); rm(df2); rm(df1); rm(numPara); rm(df1.M)

1 semaine

Extraction de l'année pour toutes les acquisitions.

annees=format(df$temps,"%Y"); head(annees)

Le numéro du jour est repéré. C'est à dire donne le jour en Julien (exemple: le 1 er février correspond au 32ème jour de l'année).

numJour=as.numeric(strftime(df$temps, "%j")); head(numJour)

Les données acquisent tous les 7 jours sont saisies, en commencant toujours par le 1er jours de l'année.

numJourSemaine=seq(1,364,by=7); numJourSemaine

Les valeurs enregistrées entre le 1er et le 7ème jour seront considérer comme acquisent le 1er jour. Les valeurs enregistrées entre le 8ème et le 15ème jour seront considérer comme acquissent le 8 ème jour, etc. Une contrainte est rajoutée pour les derniers jours, car il est fixé qu'il ne peut pas avoir plus de 52 semaines par an. Les valeurs enregistrées au delà de la 51ème semaine (358 jours) seront alors assignées à la dernière semaine. C'est à dire les jours allant de 358 à 366.

numJourT=sapply(numJour,function(x){index=max(which(x>=numJourSemaine));return(numJourSemaine[index])}); head(numJourT)

Création d'un vecteur, où y sera intergré l'année, le mois et le jour correspondant au 1er jour de chaque semaine.

df$temps=strptime(paste(numJourT,annees,sep=" "), "%j %Y"); head(df$temps)

Récupération de toutes les années présentent dans les données, mais de manière à en avoir un seul exemplaire.
Puis on divise chaque année récuprée par le nombre de semaines (52). ce vecteur sera notre date.

a=as.character(sort(unique(as.numeric(annees)))); head(a)
date=rep(a,each=52); head(date)

On crée un vecteur contenant les 1er jours (en Julien) de chaque "début" de semaines. Puis on le colle avec la date.

jour=rep(seq(1,364,by=7), length(a)); head(jour)
d=paste(date,jour,sep="-"); head(d)

Création du tableau contenant seulement les dates. Ces dates créées précédemment, contiennent simplement les jours des 1ère semaines, il y aura donc 52 valeurs pour chauqe année.

df2=data.frame(temps=strptime(d,format="%Y-%j")); df2[1:10,]

Fusion du tableau précédent avec le tableau intial.

df1=merge(df,df2, by=intersect(names(df),names(df2)),all=TRUE); df1[1:7,1:3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et ne garde la valeur maximum des doublons créés.

df.W=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
               FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
               {out=max(x,na.rm=T);}; out}); df.W[1:7,1:5]

Suppressions des données inutiles pour la suite.

rm(df1); rm(df2); rm(numPara); rm(df.W); rm(d); rm(jour); rm(a); rm(date)

1 journée

Extraction de la colonne contenant la date et mise au format POSIXt.

date=as.character((df)[,idate]); head(date)
df$temps=strptime(date, format="%Y-%m-%dT%H:%M:%SZ"); head(df$temps)

La date est de nouveau extraite (grâce aux "%F" qui correspond à AAAA-MM-JJ). Le jour est également extrait seul, puis il est remis en format POSIXt en supprimant les heures, minutes et les secondes.

date=format(df$temps,"%F"); head(date)
jours=as.numeric(format(df$temps,"%d")); head(jours)
df$temps=strptime(format(df$temps, "%F"),format="%Y-%m-%d"); head(df$temps)

Une séquence "a" est crée qui commence de la date la plus ancienne et termine à la date la plus récente.

min.date=min(df$temps,na.rm=T); min.date
max.date=max(df$temps,na.rm=T); max.date
a=seq(min.date,max.date,by="1 day"); head(a); tail(a)

De cette séquence est ensuite retirée les heures qui sont insérées automatiquement.

d=format(a,"%F"); head(d)

Création du tableau, en y incluant seulement la séquence précdemment crée (d).

df2=data.frame(temps=strptime(d,format="%Y-%m-%d")); df2[1:10,]

Fusion du tableau avec le tableau de donnée brute initial (df1).

df1=merge(df,df2, all=TRUE); df1[1:7,1,3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et ne garde la valeur maximum des doublons créés.

df.J=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
                FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
                {out=max(x,na.rm=T);}; out}); df.J[1:7,1:5]

Suppressions des données inutiles pour la suite.

rm(date); rm(jours); rm(min.date); rm(max.date); rm(a); rm(df2); rm(df1); rm(d); rm(df.J)

1 heure

Extraction de la colonne contenant la date et mise au format POSIXt.

date=as.character((df)[,idate]); head(date)
df$temps=strptime(date, format="%Y-%m-%dT%H:%M:%SZ"); head(df$temps)

La date et l'heure sont extraites, et ajoutées dans un vecteur nommé "date", tout comme l'heures (HH) qui est placée dans un vecteur nommé "heures".

date=format(df$temps,"%F"); head(date)
heures=as.numeric(format(df$temps,"%H")); head(heures)

Le vecteur "date" est collé avec le vecteur "heures", et sont rajoutés en même temps les minutes et les secondes que l'on considère égale à 00:00.
Deplus le format POSIXt est de nouveau impossé.

df$temps=strptime(format(df$temps, "%F %H:00:00"),format="%Y-%m-%d %H:%M:%S"); head(df$temps)

Cette colonne date, qui a une fréquence souhaité, débutera de la date la plus ancienne et terminera à la date la plus récente. Pour cela, voici les dates concernées.

min.date=min(df$temps,na.rm=T); min.date
max.date=max(df$temps,na.rm=T); max.date

La création de la séquence "a", qui va de la date la plus ancienne à la plus récente. De plus, la fréquence est insérer par l'argument "by".

a=seq(min.date,max.date,by="1 hour"); head(a); tail(a)

Création du tableau, en y incluant seulement le vecteur "date"" (avec l’heure, minutes et les secondes nouvellement crées).

df2=data.frame(temps=strptime(a,format="%Y-%m-%d %H:%M:%S")); df2[1:10,]

Fusion du tableau avec le tableau de donnée brute initial (df1).

df1=merge(df,df2, all=TRUE); df[1:7,1:3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et ne garde la valeur maximum des doublons créés.

df10=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
             FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
            {out=max(x,na.rm=T);}; out}); df10[1:7,1:5]

Suppressions des données inutiles pour la suite.

rm(date); rm(heures); rm(min.date); rm(max.date); rm(a); rm(df2); rm(df1); rm(numPara); rm(df10)

30 minutes

Extraction de la colonne contenant la date et mise au format POSIXt.

date=as.character((df)[,idate]); head(date)
df$temps=strptime(date, format="%Y-%m-%dT%H:%M:%SZ"); head(df$temps)

La date et l'heure sont extraites, et ajoutées dans un vecteur nommé "date".
Le vecteur "minutes" va contenir simplement les minutes qui seront extraites.

date=format(df$temps,"%F %H"); head(date)
minutes=as.numeric(format(df$temps,"%M")); head(minutes)

On considère que [hh:00, hh:29[= hh:15 et [hh:30, hh:59[= hh:45.

minute=rep("45",length(minutes));
minute[minutes<30]="15"; head(minute)

Ajout de "minute", nouvellement créée, dans la colonne date (qui contiennent l'année, le mois, le jour et l'heure, qui ont été extraits avant la modification). Il est ensuite mis sous le format POSIXt.

d=paste(date,minute,"00",sep=":"); head(d)
df$temps=strptime(d,format="%Y-%m-%d %H:%M:%S"); head(df$temps)

Cette colonne date, qui a une fréquence souhaitée, débutera de la date la plus ancienne et terminera à la date la plus récente. Pour cela, voici les dates concernées.

min.date=min(df$temps,na.rm=T); min.date
max.date=max(df$temps,na.rm=T); max.date

La création de la séquence "a", qui va de la date la plus ancienne à la plus récente. De plus la fréquence est inséée par l'argument "by".

a=seq(min.date,max.date,by="1 hour"); head(a); tail(a)
Attention, la fonction seq ne permet pas de descendre en dessous d'une heure. Il suffira alors de diviser cette heure par 2 pour obtenir les 30 minutes de la fréquence souhaitée.

%F correspond à l'année, le mois et le jour

date=rep(format(a,"%F %H"),each=2); head(date)

Les minutes sont remises en alternance entre 10, 30 et 50, sur toutes la longueur de la séquence créées.
Le vecteur minutes créé précdémment est collé avec le vecteur "date"" en y insérant le séparateur et en y ajoutant les secondes (00).

minutes=rep(c("15","45"), length(a)); head(minutes)
d=paste(date,minutes,"00",sep=":"); head(d)

Création du tableau, en y incluant seulement le vecteur "date"" (avec l’heure, minutes et les secondes nouvellement créées).

df2=data.frame(temps=strptime(d,format="%Y-%m-%d %H:%M:%S")); df2[1:10,]

Fusion du tableau avec le tableau de donnée brute initial (df1).

df1=merge(df,df2, all=TRUE); df1[1:7,1:3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et ne garde la valeur maximum des doublons créés.

df30=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
             FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
            {out=max(x,na.rm=T);}; out}); df30[1:7,1:5]

Suppressions des données inutiles pour la suite.

rm(date); rm(minutes); rm(minute); rm(min.date); rm(max.date); rm(a); rm(d); rm(df2); rm(df1); rm(numPara); rm(df30)

20 minutes

Extraction de la colonne contenant la date et mise au format POSIXt.

date=as.character((df)[,idate]); head(date)
df$temps=strptime(date, format="%Y-%m-%dT%H:%M:%SZ"); head(df$temps)

La date et l'heure sont extraites, et ajoutées dans un vecteur nommé "date".
Le vecteur "minutes" va contenir simplement les minutes qui seront extraites.
%F correspond à l'année, le mois et le jour.

date=format(df$temps,"%F %H"); head(date)
minutes=as.numeric(format(df$temps,"%M")); head(minutes)

On considère que [hh:00, hh:20[= hh:10, [hh:20, hh:40[= hh:30 et pour [hh:40, hh:59]= hh:50.

minute=rep("10",length(minutes))
minute[minutes>19]="30"
minute[minutes>40]="50"; head(minute)

Ajout de "minute", nouvellement créée, dans la colonne date (qui contiennent l'année, le mois, le jour et l'heure, qui ont été extraits avant la modification), et ajout des secondes mis à "00". Il est ensuite mis sous le format POSIXt.

d=paste(date,minute,"00",sep=":"); head(d)
df$temps=strptime(d,format="%Y-%m-%d %H:%M:%S"); head(df$temps)

Cette colonne date, qui a une fréquence souhaitée, débutera de la date la plus ancienne et terminera à la date la plus récente. Pour cela, voici les dates concernées.

min.date=min(df$temps,na.rm=T); min.date
max.date=max(df$temps,na.rm=T); max.date

La création de la séquence "a", qui va de la date la plus ancienne à la plus récente. De plus la fréquence est insérée par l'argument "by".

a=seq(min.date,max.date,by="1 hour"); head(a); tail(a)
Attention, la fonction seq ne permet pas de descendre en dessous d'une heure. Il suffira alors de diviser cette heure par 3 pour obtenir les 20 minutes de la fréquence souhaitée.

%F correspond à l'année, mois et le jour.

date=rep(format(a,"%F %H"),each=3); head(date)

Les minutes sont remises en alternance entre 10, 30 et 50, sur toute la longueur de la séquence créer.
Le vecteur minutes créé précdémment est collé avec le vecteur "date"" en y insérant le séparateur et en y ajoutant les secondes (00).

minutes=rep(c("10","30","50"), length(a)); head(minutes)
d=paste(date,minutes,"00",sep=":"); head(d)

Création du tableau, en y incluant seulement le vecteur "date"" (avec l’heure, minutes et les secondes nouvellement créées).

df2=data.frame(temps=strptime(d,format="%Y-%m-%d %H:%M:%S")); df2[1:10,]

Fusion du tableau avec le tableau de donnée brute initial (df1).

df1=merge(df,df2, all=TRUE); df1[1:7,1:3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et ne garde la valeur maximum des doublons créés.

df20=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
             FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
            {out=max(x,na.rm=T);}; out}); df20[1:7,1:5]

Suppressions des données inutiles pour la suite.

rm(date); rm(minutes); rm(minute); rm(min.date); rm(max.date); rm(a); rm(d); rm(df2); rm(df1); rm(numPara); rm(df20)

10 minutes

Extraction de la colonne contenant la date et mise au format POSIXt.

date=as.character((df)[,idate]); head(date)
df$temps=strptime(date, format="%Y-%m-%dT%H:%M:%SZ"); head(df$temps)

La date et l'heure sont extraites, et ajoutées dans un vecteur nommé "date".
Le vecteur "minutes" va contenir simplement les minutes qui seront extraites.

date=format(df$temps,"%F %H"); head(date)
minutes=as.numeric(format(df$temps,"%M")); head(minutes)

On considère que [hh:00, hh:10[= hh:05, [hh:10, hh:20[= hh:15, [hh:20, hh:30[= hh:25, [hh:30, hh:40[= hh:35, [hh:40, hh:50]= hh:45 et pour [hh:50, hh:59]= hh:55.

minute=rep("05",length(minutes))
minute[minutes>10]="15"
minute[minutes>20]="25"
minute[minutes>30]="35"
minute[minutes>40]="45"
minute[minutes>50]="55"; head(minute)

Ajout de "minute", nouvellement créées, dans la colonne date (qui contiennent l'année, le mois, le jour et l'heure, qui ont été extraites avant la modification). Il est ensuite mis sous le format POSIXt.

d=paste(date,minute,"00",sep=":"); head(d)
df$temps=strptime(d,format="%Y-%m-%d %H:%M:%S"); head(df$temps)

Cette colonne date, qui a une fréquence souhaitée, débutera de la date la plus ancienne et terminera à la date la plus récente. Pour cela, les dates concernées sont repérées et enregistrées.

min.date=min(df$temps,na.rm=T); min.date
max.date=max(df$temps,na.rm=T); max.date

La création de la séquence "a", qui va de la date la plus ancienne à la plus récente. De plus la fréquence est insérée par l'argument "by".

a=seq(min.date,max.date,by="1 hour"); head(a); tail(a)
Attention, la fonction seq ne permet pas de descendre en dessous d'une heure. Il suffira alors de diviser cette heure par 6 pour obtenir les 10 minutes de la fréquence souhaitée.

date=rep(format(a,"%F %H"),each=6); head(date)

Les minutes sont remises en alternance entre 05, 15, 25, 35, 45, et 55, sur toute la longueur de la séquence créées.
Le vecteur minutes créé précdémment est coller avec le vecteur "date"" en y insérant le séparateur et en y ajoutant les secondes (00).

minutes=rep(c("05", "15","25", "35", "45", "55"), length(a)); head(minutes)
d=paste(date,minutes,"00",sep=":"); head(d)

Création du tableau, en y incluant seulement le vecteur "date"" (avec l’heure, minutes et les secondes nouvellement crée).

df2=data.frame(temps=strptime(d,format="%Y-%m-%d %H:%M:%S")); df2[1:10,]

Fusion du tableau avec le tableau de donnée brute initial (df1).

df1=merge(df,df2, all=TRUE); df1[1:7,1:3]

Sélection des colonnes contenant que l'on souhaite agrégée. Attention ces colonnes doivent être de type numérique.

Voici comment voir la classe des paramètres

classe=sapply(df, FUN=class); head(classe)
numPara=5:26 # colonnes séléctionnées : 5 à 26

De ce nouveau tableau seulement les colonnes voulues sont extraites, et ne garde la valeur maximum des doublons créés.

df10=aggregate(df1[,numPara],by=list(temps=as.character(df1$temps)),
             FUN=function(x){ out=NA; if(sum(is.na(x))<length(x))
            {out=max(x,na.rm=T);}; out}); df10[1:7,1:5]

Création du fichier compatible avec uHMM

L'interface uHMM exige certaine condition supplémentaire de l'alignement. Il faut avoir une colonne contenant que la date et une autre colonne contenant les heures. Pour cela, la création de 2 vecteurs est essentielle, l'un contenant la date et l'autre contenant l'heure.
Ces 2 lignes de code le permettent :

colonneDate=as.character(format(df$temps,"%F"))
colonneHeure=as.character(format(df$temps,"%X"))
"df" étant votre tableau de donnée que vous souhaitez faire lire par l'interface. "%F" retire les années, le mois et le jour (AAAA-MM-JJ) et "%X" retire les heures, les minutes et les secondes (hh:mm:ss).

L'indice de la colonne temps sera alors retiré pour laisser place aux 2 colonnes créées précédemment. On repère alors la colonne temps.

iTemps=grep(pattern="temps",names(df))

Puis on crée un nouveau taleau de données avec comme première varaible la date, et comme deuxième varaiable l'heure. Ces 2 colonnes devront se nommer exactement "Dates" et "Hours" (exigence de l'interface). De plus nous retirons la colonne temps.

df.cor=data.frame(Dates=colonneDate,Hours=colonneHeure,(df[,-iTemps]))

Il ne reste plus qu'à le transformer sous le format texte (.txt).

write.table(df.cor,file="uHMMcorrectedQuentin.txt",dec='.',sep="\t", quote=FALSE, row.names=FALSE)