сопоставление векторов времени различной длины: сложный - PullRequest
3 голосов
/ 23 июня 2011

У меня есть два набора измерений от разных машин.Они измеряются с течением времени, с немного разными интервалами - например, один производит измерение каждые 5 минут, а другой - каждые 3 минуты.Преимущество состоит в том, что значение каждые 5 минут вычисляется как среднее значение по всему интервалу, поэтому значения должны приблизительно соответствовать друг другу.Я хотел бы расширить вектор измерениями каждые 5 минут (Light), чтобы его значения были примерно синхронны со значениями в векторе измерений, выполненными каждые 5 минут.Затем следует заполнить пробел предыдущим значением

. Вот пример данных каждые 5 минут

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 

и данных каждые 3 минуты

    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

Не следует также, чтобы вектор измерения освещенности (каждые 5 минут) был короче, чем вектор каждые 3 минуты.Таким образом, цель состоит в том, чтобы сделать вектор 5-минутных измерений такой же длины, как и 3-минутный вектор.

Я понимаю, что это довольно сложная проблема, но любые предложения будут приняты с большим удовольствием.

Ответы [ 2 ]

3 голосов
/ 23 июня 2011

Если я правильно понимаю, это легко сделать с помощью zoo или xts. Во-первых, вот ваши образцы данных:

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)

Теперь мы загружаем пакет xts, который также загружает zoo. Затем мы конвертируем объекты Light и Flux data.frame в объекты 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"))

Вот отличная часть. merge.xts и merge.zoo выровняют каждую серию по индексу. na.locf заполняет каждое NA предыдущим значением.

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)

Наконец, мы можем извлечь 3-минутный индекс из объединенного объекта Data.

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
3 голосов
/ 23 июня 2011

Вы можете использовать ок , который будет линейно интерполировать между вашими точками данных. Вот быстрый пример:

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

Чтобы указать, сколько точек вы хотите интерполировать, вы можете использовать параметр xout, например:

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

Для дополнительных точек интерполяции:

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

В вашем конкретном примере вы захотите сделать что-то вроде интерполяции значений x, y обеих функций, используя пересечение временных точек из обеих машин. Вот одно предложение:

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

Затем вы можете использовать этот x_interp в качестве xout для интерполяции между точками с обеих машин:

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 )

Если вы хотите получить функцию, которая интерполирует значения для произвольных входных данных, см. Связанную функцию, называемую приблизительный .

...