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 :

Interpolation Linéaire NAs


Sujet :

R

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 69
    Points : 38
    Points
    38
    Par défaut Interpolation Linéaire NAs
    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 : 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
     
    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 : 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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    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..

    En pièce jointe, une partie du fichier de données.

    Merci beaucoup pour votre aide!
    Fichiers attachés Fichiers attachés

  2. #2
    Membre confirmé
    Homme Profil pro
    MCU
    Inscrit en
    Juillet 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : MCU
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2010
    Messages : 185
    Points : 486
    Points
    486
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ?approx
    approx(x=c(14.5, 16.5), y=c(17.657, 18.228), xout=seq(15,16, 1/6))
    HTH

    Vincent

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 69
    Points : 38
    Points
    38
    Par défaut
    Bonjour et merci pour la réponse!
    Cependant, le fichier de données que j'ai envoyé n'est qu'un aperçu du fichier d'origine qui est beaucoup plus long. Je souhaiterais donc automatiser le traitement pour ne pas avoir à repérer moi-même les données manquantes (NA) à combler et changer à chaque fois les paramètres de la fonction "approx". C'est pour cette raison que je n'utilise pas cette fonction. Peut-être est-ce d'ailleurs une erreur car il pourrait être facile de repérer les NA avec une petite boucle for ou while et d'ajuster pour chaque donnée manquante les paramètres de la fonction approx. Je vais tenter ça et j'envoie le script!

  4. #4
    Membre éprouvé

    Homme Profil pro
    Cyber Security & AI
    Inscrit en
    Février 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Cyber Security & AI

    Informations forums :
    Inscription : Février 2009
    Messages : 506
    Points : 1 189
    Points
    1 189
    Billets dans le blog
    2
    Par défaut
    Pour extraire les valeurs null d'une data.frame, tu n'as pas besoin de faire une boucle. Il suffit d’écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[is.na(data$Temp)==FALSE]
    Avec data le nom de tes données.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 69
    Points : 38
    Points
    38
    Par défaut
    Cette ligne de code ne fonctionne pas. Voici le message d'erreur qui m'est renvoyé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > tab[is.na(tab$Temp)==FALSE]
    Error in `[.data.frame`(tab, is.na(tab$Temp) == FALSE) : 
      undefined columns selected
    J'utilise simplement ça pour repérer mes NA dans une nouvelles colonne appelée "Miss":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab$Miss=is.na(tab$Temp)
    Je me remets seulement sur ce problème, je ne manque pas de poster dès que j'avance!
    Merci pour votre aide.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 69
    Points : 38
    Points
    38
    Par défaut
    Re-bonjour!
    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 :

    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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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!

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 69
    Points : 38
    Points
    38
    Par défaut
    C'est bon j'ai trouvé! Voici le code:

    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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
         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!

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 19/08/2009, 12h02
  2. [XL-2003] création d'une interpolation linéaire.
    Par Piccou dans le forum Excel
    Réponses: 5
    Dernier message: 30/07/2009, 09h51
  3. algorithme d'interpolation linéaire
    Par kromartien dans le forum Mathématiques
    Réponses: 5
    Dernier message: 11/04/2007, 09h55
  4. Interpolation "linéaire" sur un point dans triangle (3D)
    Par Vol dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 09/07/2006, 22h34

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