2011-06-23 3 views
3

J'ai deux ensembles de mesures de différentes machines. Ils sont mesurés dans le temps, à des intervalles légèrement différents - par ex. on fait une mesure toutes les 5 minutes, mais l'autre, toutes les 3 minutes. L'avantage est que toutes les 5 minutes sont calculées en moyenne sur l'ensemble de l'intervalle, de sorte que les valeurs doivent correspondre grossièrement les unes aux autres. Je voudrais étendre le vecteur avec des mesures toutes les 5 minutes (Light) de sorte que ses valeurs sont à peu près synchrones avec les valeurs dans le vecteur de mesures faites toutes les 5 minutes. L'écart doit alors être rempli avec la valeur précédentevecteurs de temps correspondant de longueur différente: un difficile

Voici un exemple des données toutes les 5 minutes

Date    Light 
26/05/2011 16:00 -529.98    
26/05/2011 16:05 -276.68    
26/05/2011 16:10 -179.63    
26/05/2011 16:15 -385.57    
26/05/2011 16:20 -1273.6    
26/05/2011 16:25 -1109.7 

et les données toutes les 3 minutes

Date    Flux 
26/05/2011 16:01  0.64 
26/05/2011 16:04 -1.96 
26/05/2011 16:07 -0.51 
26/05/2011 16:10 -1.34 
26/05/2011 16:13 -1.28 
26/05/2011 16:15 -0.22 

Je devrais pas non plus que la Le vecteur de mesure de la lumière (toutes les 5 minutes) est plus court que le vecteur toutes les 3 minutes. Le but est donc de rendre le vecteur de mesures de 5 minutes de la même longueur que le vecteur de 3 minutes. Je me rends compte que c'est un problème assez difficile, mais toutes les suggestions seraient grandement reçues.

Répondre

3

Si je comprends bien, ceci est facilement accompli avec zoo ou xts. Tout d'abord, voici vos exemples de données:

Lines1 <- "Date,Light 
26/05/2011 16:00,-529.98 
26/05/2011 16:05,-276.68 
26/05/2011 16:10,-179.63 
26/05/2011 16:15,-385.57 
26/05/2011 16:20,-1273.6 
26/05/2011 16:25,-1109.7" 

Lines2 <- "Date,Flux 
26/05/2011 16:01,0.64 
26/05/2011 16:04,-1.96 
26/05/2011 16:07,-0.51 
26/05/2011 16:10,-1.34 
26/05/2011 16:13,-1.28 
26/05/2011 16:15,-0.22" 

con <- textConnection(Lines1) 
Light <- read.csv(con, stringsAsFactors=FALSE, header=TRUE) 
close(con) 
con <- textConnection(Lines2) 
Flux <- read.csv(con, stringsAsFactors=FALSE, header=TRUE) 
close(con) 

Maintenant, nous chargeons le paquet xts, qui charge également zoo. Ensuite, nous convertissons les objets Light et Flux data.frame en objets xts.

library(xts) 
light <- xts(Light$Light, as.POSIXct(Light$Date, format="%d/%m/%Y %H:%M")) 
flux <- xts(Flux$Flux, as.POSIXct(Flux$Date, format="%d/%m/%Y %H:%M")) 

Voici la partie géniale. merge.xts et merge.zoo alignera chaque série par index. na.locf remplit chaque NA avec la valeur précédente.

Data <- merge(light,flux) 
#      light flux 
# 2011-05-26 16:00:00 -529.98 NA 
# 2011-05-26 16:01:00  NA 0.64 
# 2011-05-26 16:04:00  NA -1.96 
# 2011-05-26 16:05:00 -276.68 NA 
# 2011-05-26 16:07:00  NA -0.51 
# 2011-05-26 16:10:00 -179.63 -1.34 
# 2011-05-26 16:13:00  NA -1.28 
# 2011-05-26 16:15:00 -385.57 -0.22 
# 2011-05-26 16:20:00 -1273.60 NA 
# 2011-05-26 16:25:00 -1109.70 NA 
Data <- na.locf(Data) 

Enfin, on peut extraire l'indice 3 minutes de l'objet Data fusionné.

Data[index(flux),] 
#      light flux 
# 2011-05-26 16:01:00 -529.98 0.64 
# 2011-05-26 16:04:00 -529.98 -1.96 
# 2011-05-26 16:07:00 -276.68 -0.51 
# 2011-05-26 16:10:00 -179.63 -1.34 
# 2011-05-26 16:13:00 -179.63 -1.28 
# 2011-05-26 16:15:00 -385.57 -0.22 
+0

+1 pour l'explication zoo/xts. J'allais laisser un commentaire que zoo/xts a ce genre de chose intégré, mais n'était pas assez familier avec cela pour divertir fournir une réponse. –

+0

Cest incroyable! Je vous remercie –

3

Vous pouvez utiliser approx, qui interpolera linéairement entre vos points de données. Voici un exemple rapide:

x = sort(rnorm(20)) 
y = 1:20 
plot(x, y, main = 'function interpolation example') 
points(approx(x, y), col = 2, pch = 3) 

Pour spécifier le nombre de points que vous voulez interpoler, vous pouvez utiliser le paramètre xout, comme ceci:

points(approx(x, y, xout = seq(from = min(x), to = max(x), by = 0.1)), pch = 3, col = 3) 

Pour plus de points d'interpolation:

points(approx(x, y, xout = seq(from = min(x), to = max(x), by = 0.05)), pch = 3, col = 4) 

Pour votre exemple spécifique, vous voudriez faire quelque chose comme interpoler les valeurs x, y des deux fonctions en utilisant l'intersection des points temporels des deux machines. Voici une suggestion:

x_interp = unique(sort(c(seq(from = 0, to = 100, by = 5), seq(from = 0, to = 100, by = 3)))) 
x_interp 
[1] 0 3 5 6 9 10 12 15 18 20 21 24 25 27 30 33 35 
[18] 36 39 40 42 45 48 50 51 54 55 57 60 63 65 66 69 70 
[35] 72 75 78 80 81 84 85 87 90 93 95 96 99 100 

Ensuite, vous pouvez utiliser cette x_interp comme xout interpoler entre les points des deux machines:

par(mfrow = c(1,2)) 
plot(x_light, y_light) 
points(approx(x_light, y_light, x_out = x_interp), col = 2, pch = 3) 

plot(x_flux, y_flux) 
points(approx(x_flux, y_flux, x_out = x_interp), col = 3, pch = 3) 

Si vous souhaitez obtenir une fonction qui interpole les valeurs de entrées arbitraires, voir la fonction associée appelée approxfun.

+0

+1 pour 'approx()'. Vouliez-vous utiliser 'approxfun()' ou mentionner 'approx()' - il y a une déconnexion mineure entre le code et la première ligne de votre réponse? –

+0

+1 C'est ce que j'ai fait avec un problème similaire –

+0

@Gavin - great point. Changé la première ligne, ajouté une ligne de fin. N'hésitez pas à modifier si vous souhaitez améliorer la réponse. –

Questions connexes