Interpolation Linéaire NAs

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

Robin Caillon
Messages : 49
Enregistré le : 21 Déc 2012, 11:12

Interpolation Linéaire NAs

Messagepar Robin Caillon » 04 Avr 2014, 15:28

Bonjour,
Je dispose d'un jeu de données de température avec un pas de temps semi-horaire (30 min). Je souhaite procéder à une interpolation linéaire afin d'obtenir un pas de temps de 10 min. Cependant, le jeu de données est composé de quelques NA que je souhaite prendre en compte dans l'interpolation. Ainsi, lorsqu'une donnée manque (NA), je souhaite considérer la valeur suivante pour procéder à l'interpolation et augmenter mon pas de temps mais également recalculer par la même occasion la valeur manquante. Exemple:

Code : Tout sélectionner

date   heure   Temp
6062012   800   15.026
6062012   830   15.481
6062012   900   15.892
6062012   930   16.374
6062012   1000   16.952
6062012   1030   16.884
6062012   1100   NAN
6062012   1130   17.947
6062012   1200   18.056
6062012   1230   18.177
6062012   1300   19.057
6062012   1330   18.716
6062012   1400   18.872
6062012   1430   17.657
6062012   1500   NAN
6062012   1530   NAN
6062012   1600   NAN
6062012   1630   18.228
6062012   1700   18.335



Ici, 1430 correspond à 14h30. Je souhaite donc procéder à une interpolation linéaire entre les valeurs de température des lignes 6 et 8 pour générer des valeurs à 15h10, 15h20, calculer la valeur manquante à 15h30 (ligne 7), et enfin 15h40 et 15h50.

Je me suis lancé dans un code assez long... qui ne fonctionne pas! et je ne comprends pas pourquoi. Le voici:

Code : Tout sélectionner

tab=read.table("test.txt",header=TRUE)
t=1
tab1=tab[c(1:t),]

for (t in 1:length(tab$Tair)){
  if (tab$Tair[t]=="NAN"){
    b=tab[c(t-1,t+1),]
    v=tab$heure[t-1]
    time=c(v,v+60)
    b=cbind(b,time)
    b[,3]=as.numeric(b[,3])
    b[,4]=as.numeric(b[,4])
    reg=lm(b[,3]~b$time)
    a=as.vector(reg$coeff[2])
    b=as.vector(reg$coeff[1])
    for (i in seq(10,20,by=10)){
      tabtemp=data.frame(matrix(ncol=3,nrow=1))
      colnames(tabtemp)=c("date","heure","Tair")
      x=tab$time[2]+i
      y=a*x+b
      z=tab$date[t]
      u=tab$heure[t]+i
      tabtemp[1,]=c(z,u,y)
      tab1=rbind(tab1,tabtemp)
    }
    }else{
    if (tab$Tair[t+1]=="NAN"){
      b=tab[c(t,t+2),]
      v=tab$heure[t]
      time=c(v,v+60)
      b=cbind(b,time)
      b[,3]=as.numeric(b[,3])
      b[,4]=as.numeric(b[,4])
      reg=lm(b[,3]~b$time)
      a=as.vector(reg$coeff[2])
      b=as.vector(reg$coeff[1])
      for (i in seq(10,20,by=10)){
        tabtemp=data.frame(matrix(ncol=3,nrow=1))
        colnames(tabtemp)=c("date","heure","Tair")
        x=tab$heure[t]+i
        y=a*x+b
        z=tab$date[t]
        tabtemp[1,]=c(z,x,y)
        tab1=rbind(tab1,tabtemp)
      }
      tabtemp=data.frame(matrix(ncol=3,nrow=1))
      colnames(tabtemp)=c("date","heure","Tair")
      x=tab$heure[t]+30
      y=a*x+b
      z=tab$date[t]
      u=tab$heure[t+1]
      tabtemp[1,]=c(z,u,y)
      tab1=rbind(tab1,tabtemp)
      }else{
      b=tab[c(t,t+1),]
      v=tab$heure[t]
      time=c(v,v+30)
      b=cbind(b,time)
      b[,3]=as.numeric(b[,3])
      b[,4]=as.numeric(b[,4])
      reg=lm(b[,3]~b$time)
      a=as.vector(reg$coeff[2])
      b=as.vector(reg$coeff[1])
      for (i in seq(10,20,by=10)){
        tabtemp=data.frame(matrix(ncol=3,nrow=1))
        colnames(tabtemp)=c("date","heure","Tair")
        x=tab$heure[t]+i
        y=a*x+b
        z=tab$date[t]
        tabtemp[1,]=c(z,x,y)
        tab1=rbind(tab1,tabtemp)
      }
      tabtemp2=data.frame(matrix(ncol=3,nrow=1))
      colnames(tabtemp2)=c("date","heure","Tair")
      tabtemp2[1,]=tab[t+1,]
      tab1=rbind(tab1,tabtemp2)
    }
  }
}
}

tab1


Ce code ne prend pour l'instant pas en compte le fait que l'on puisse rencontrer plusieurs NA consécutifs. Je ne voulais pas faire trop compliqué pour commencer..

J'aurais voulu mettre un exemple des données en pièce jointe mais je ne vois pas comment faire :s

Merci beaucoup pour votre aide!

Robin Caillon
Messages : 49
Enregistré le : 21 Déc 2012, 11:12

Messagepar Robin Caillon » 17 Avr 2014, 07:49

Re-bonjour!
Je reviens à la charge puisque j'ai repris le problème en main hier.
Finalement j'ai choisi de traiter mon problème en 2 fois. D'abord remplacer les valeurs manquantes dans mes données de températures en interpolant à partir des valeurs les plus proches dans le temps. Ensuite interpoler pour affiner mon pas de temps (30min-->10min).

Voici le code que j'ai fait pour calculer mes données manquantes par interpolation : (je n'ai pas encore attaqué la partie 2 d'affinage du pas de temps)

Code : Tout sélectionner

tab=read.table("test.txt",header=TRUE)
tab$newtemp=NA

for (t in 1:length(tab$temp)){
  row=numeric(0)
  if (tab$temp[t]==NA){
    while (tab$temp[t]==NA)
    { 
      row=c(row,t)
      t=t+1
    }
    mini=min(row)
    maxi=max(row)
    b=tab[c(mini-1,maxi+1),]
    b$time=(1:(maxi+1)) 
    b[,3]=as.numeric(b[,3])
    b[,4]=as.numeric(b[,4])
    reg=lm(b[,3]~b[,4])
    a=as.vector(reg$coeff[2])
    b=as.vector(reg$coeff[1])
    for (i in 2:(length(b[,4]))){
      x=i
      tab$newtemp[(row[i])]=a*x+b
    }
  }
}


R me renvoie alors ce message d'erreur:

Code : Tout sélectionner

Error in if (tab$temp[t] == NA) { : missing value where TRUE/FALSE needed


Sauriez-vous m'expliquer pourquoi? Qu'est-ce qui ne va pas dans mon code? Pour l'instant je ne vois pas...

Merci pour votre aide!

denis laloe
Messages : 119
Enregistré le : 28 Déc 2006, 13:05

Messagepar denis laloe » 17 Avr 2014, 08:08

Bonjour,

je pense que le code correct pour tester si une valeur est manquante est
"is.na". cf exemple suivant


avd<-1
> avd==NA
[1] NA
> is.na(avd)
[1] FALSE

Robin Caillon
Messages : 49
Enregistré le : 21 Déc 2012, 11:12

Messagepar Robin Caillon » 17 Avr 2014, 08:59

C'est bon j'ai trouvé! Voici le code:

Code : Tout sélectionner

tab=read.table("test6.txt",header=TRUE)

for (t in 1:length(tab$temp)){
  row=numeric(0)
  if ((is.na(tab$temp[t]))==TRUE){
    while ((is.na(tab$temp[t]))==TRUE)
    { 
      row=c(row,t)
      t=t+1
    }
    mini=min(row)
    maxi=max(row)
    subtab=tab[c((mini-1):(maxi+1)),]
    subtab$time=c(1:((length(row)+2))) 
    reg=lm(subtab$temp~subtab$time)
    a=as.vector(reg$coeff[2])
    b=as.vector(reg$coeff[1])
    i=1
    for (x in 2:(length(subtab$time)-1)){
      tab$temp[(row[i])]=a*x+b
      i=i+1
    }
  }
}


Ca me permet de passer de ce tableau de données:

Code : Tout sélectionner

    date heure temp
1 1012013     0    0
2 1012013    30   NA
3 1012013   100   NA
4 1012013   130   NA
5 1012013   200   NA
6 1012013   230   10


A celui-ci:

Code : Tout sélectionner

     date heure temp
1 1012013     0    0
2 1012013    30    2
3 1012013   100    4
4 1012013   130    6
5 1012013   200    8
6 1012013   230   10


Il est peut-être possible de faire plus simple mais en attendant ça fonctionne! Merci pour votre aide!

Robin Caillon
Messages : 49
Enregistré le : 21 Déc 2012, 11:12

Messagepar Robin Caillon » 17 Avr 2014, 15:45

Je ne sais pas comment indiquer que le problème est résolu.. dsl

Clement Clasquin
Messages : 9
Enregistré le : 08 Juin 2015, 09:07

Re: Interpolation Linéaire NAs

Messagepar Clement Clasquin » 15 Juin 2015, 13:46

Salut! as tu trouvé pour l'affinage de ton pas de temps à 10min? J'ai un problème similaire, pour affiner mon pas de temps en passant du jour à l'heure (*24 sur mon jeu de données). Donc si tu as quelque chose, je suis plus que preneur!

jean lobry
Messages : 733
Enregistré le : 17 Jan 2008, 20:00
Contact :

Re:

Messagepar jean lobry » 15 Juin 2015, 17:41

Robin Caillon a écrit :Je ne sais pas comment indiquer que le problème est résolu.. dsl

Bonjour,

j'ai eu le même problème naguère, la soluce est .

Amicalement,

Jean


Retourner vers « Questions en cours »

Qui est en ligne

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

cron