【问题标题】:matching time vectors of different length: a tricky one匹配不同长度的时间向量:一个棘手的问题
【发布时间】:2011-09-21 10:01:20
【问题描述】:

我有两组来自不同机器的测量值。它们随着时间的推移以略微不同的间隔进行测量 - 例如一个每 5 分钟测量一次,而另一个每 3 分钟测量一次。优点是每 5 分钟计算一次作为整个间隔的平均值,因此这些值应该大致对应。我想用每 5 分钟测量一次的向量(光)来扩展向量,以便它的值与每 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 分钟向量的长度相同。

我意识到这是一个相当棘手的问题,但任何建议都会受到欢迎。

【问题讨论】:

    标签: r xts zoo


    【解决方案1】:

    如果我理解正确,这很容易通过 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)
    

    最后,我们可以从合并的Data对象中提取3分钟的索引。

    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
    

    【讨论】:

    • +1 用于 zoo/xts 解释。我打算发表评论说 zoo/xts 内置了这种东西,但对它还不够熟悉,无法提供答案。
    【解决方案2】:

    您可以使用approx,它将在您的数据点之间进行线性插值。这是一个简单的例子:

    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 )
    

    如果您想获得一个为任意输入插值的函数,请参阅名为 approxfun 的相关函数。

    【讨论】:

    • +1 表示approx()。您的意思是使用approxfun() 还是提及approx() - 代码和答案的开头行之间存在细微的脱节?
    • @Gavin - 好点子。更改了第一行,添加了结束行。如果您想改进答案,请随时编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多