【问题标题】:Merge two dataframes with different time ranges by repeating values within time range in R通过在 R 中的时间范围内重复值来合并具有不同时间范围的两个数据帧
【发布时间】:2020-04-04 17:59:46
【问题描述】:

我有两个不同的数据框,它们都有一个时间信息列,具有不同的时间间隔。第一个 df1 的时间间隔以秒 (~6s) 为单位,另一个 (df2) 的时间间隔为 10 分钟。 我想合并两个数据框,保留来自两个 df 的信息,在 df1 的时间范围内重复 df2 值。 像这样:

df1

  x   y   z     time
-52 -39 -35 06:08:03
-47 -57 -36 06:08:08
-39   2 -40 06:08:13
-45 -23 -29 06:10:20
-51 -11 -31 06:10:29
-69 -28 -19 06:20:34

df2

time        Temp.ar  Ur ar  Vel. Vento
06:00:00    14.79    78.5   1.147
06:10:00    14.74    78.9   1.045
06:20:00    14.9     78.9   1.009
06:30:00    15.14    78.6   1.076
06:40:00    15.32    77.8   1.332
06:50:00    15.6     76.5   1.216   

我想要的输出

 x   y   z      time  Temp.ar   Ur ar   Vel. Vento
-52 -39 -35 06:08:03  14.79     78.5    1.147
-47 -57 -36 06:08:08  14.79     78.5    1.147
-39   2 -40 06:08:13  14.79     78.5    1.147
-45 -23 -29 06:10:20  14.74     78.9    1.045
-51 -11 -31 06:10:29  14.74     78.9    1.045
-69 -28 -19 06:20:34  14.9      78.9    1.009

时间列已经是“POSIXct”格式。

【问题讨论】:

  • 您要使用什么映射?从06:00:00df1 中的06:10:00 的任何时间是否与df2 中的06:00:00 时间相匹配?我想这取决于df2 是否有位置或平均值的点估计,如果是平均值,则在什么时间。
  • 提供正确的reprex。它可以帮助谁回答您的问题,因此,它也可以帮助您。
  • 不,df1 中的时间开始于与 df2 不同的时间,所以我必须间隔,例如从 06:00:00 到 06:10:00 我必须重复其他变量(Temp.ar、Ur ar 和 Vel. Vento)从 06:10:00 到 df2,依此类推。

标签: r time merge time-series intervals


【解决方案1】:

可能最通用的方法是定义一组时间窗口,然后使用findInterval 来定位每个数据帧中时间的索引。然后您可以使用merge 将两者结合在一起:

# This is what Gabriel means by a reprex - if you provide the data in 
# loadable form it is much easier to help
df1 <- read.table(text="  x   y   z     time
-52 -39 -35 06:08:03
-47 -57 -36 06:08:08
-39   2 -40 06:08:13
-45 -23 -29 06:10:20
-51 -11 -31 06:10:29
-69 -28 -19 06:20:34", header=TRUE, stringsAsFactors=FALSE)

df2 <- read.table(text="time        Temp.ar  Ur.ar  Vel.Vento
06:00:00    14.79    78.5   1.147
06:10:00    14.74    78.9   1.045
06:20:00    14.9     78.9   1.009
06:30:00    15.14    78.6   1.076
06:40:00    15.32    77.8   1.332
06:50:00    15.6     76.5   1.216", header=TRUE, stringsAsFactors=FALSE)

df1$time <- strptime(df1$time, '%H:%M:%S')
df2$time <- strptime(df2$time, '%H:%M:%S')

# I'm just using the existing sequence in df2 as the time windows, but
# you could set up different ones
df1$interval <- findInterval(df1$time, df2$time)
df2$interval <- findInterval(df2$time, df2$time)

df3 <- merge(df1, df2, by='interval')

其中有一些额外的列(来自 df1 和 df2 的时间),但您可以将它们子集化。不过,它们是一项有用的检查。

【讨论】:

    【解决方案2】:

    您可以使用滚动连接

    library(data.table)
    setDT(df1)
    setDT(df2)
    
    df2[df1, on = .(time), roll = TRUE]
    
    #                   time Temp.ar Ur.ar Vel.Vento   x   y   z
    # 1: 2019-12-11 06:08:03   14.79  78.5     1.147 -52 -39 -35
    # 2: 2019-12-11 06:08:08   14.79  78.5     1.147 -47 -57 -36
    # 3: 2019-12-11 06:08:13   14.79  78.5     1.147 -39   2 -40
    # 4: 2019-12-11 06:10:20   14.74  78.9     1.045 -45 -23 -29
    # 5: 2019-12-11 06:10:29   14.74  78.9     1.045 -51 -11 -31
    # 6: 2019-12-11 06:20:34   14.90  78.9     1.009 -69 -28 -19
    

    使用的数据

    df1 <- fread('
    x   y   z     time
    -52 -39 -35 06:08:03
    -47 -57 -36 06:08:08
    -39   2 -40 06:08:13
    -45 -23 -29 06:10:20
    -51 -11 -31 06:10:29
    -69 -28 -19 06:20:34
    ')
    
    df2 <- fread('
    time        Temp.ar  Ur.ar  Vel.Vento
    06:00:00    14.79    78.5   1.147
    06:10:00    14.74    78.9   1.045
    06:20:00    14.9     78.9   1.009
    06:30:00    15.14    78.6   1.076
    06:40:00    15.32    77.8   1.332
    06:50:00    15.6     76.5   1.216
    ')
    

    【讨论】:

      【解决方案3】:

      使用base R,这里提供了两种方法可以帮助您实现它,

      • 使用findInterval():
      df <- `row.names<-`(cbind(df1,df2[findInterval(df1$time, df2$time),-1]),rownames(df1))
      
      • 使用which.max():
      df <- `row.names<-`(cbind(df1,
                                df2[sapply(df1$time, 
                                           function(x) which.max(df2$time >= x)-1),-1]),rownames(df1)) 
      

      给了

      > df
          x   y   z                time Temp.ar Ur.ar Vel.Vento
      1 -52 -39 -35 2019-12-11 06:08:03   14.79  78.5     1.147
      2 -47 -57 -36 2019-12-11 06:08:08   14.79  78.5     1.147
      3 -39   2 -40 2019-12-11 06:08:13   14.79  78.5     1.147
      4 -45 -23 -29 2019-12-11 06:10:20   14.74  78.9     1.045
      5 -51 -11 -31 2019-12-11 06:10:29   14.74  78.9     1.045
      6 -69 -28 -19 2019-12-11 06:20:34   14.90  78.9     1.009
      

      数据

      df1 <- structure(list(x = c(-52L, -47L, -39L, -45L, -51L, -69L), y = c(-39L, 
      -57L, 2L, -23L, -11L, -28L), z = c(-35L, -36L, -40L, -29L, -31L, 
      -19L), time = structure(list(sec = c(3, 8, 13, 20, 29, 34), min = c(8L, 
      8L, 8L, 10L, 10L, 20L), hour = c(6L, 6L, 6L, 6L, 6L, 6L), mday = c(11L, 
      11L, 11L, 11L, 11L, 11L), mon = c(11L, 11L, 11L, 11L, 11L, 11L
      ), year = c(119L, 119L, 119L, 119L, 119L, 119L), wday = c(3L, 
      3L, 3L, 3L, 3L, 3L), yday = c(344L, 344L, 344L, 344L, 344L, 344L
      ), isdst = c(0L, 0L, 0L, 0L, 0L, 0L), zone = c("CET", "CET", 
      "CET", "CET", "CET", "CET"), gmtoff = c(NA_integer_, NA_integer_, 
      NA_integer_, NA_integer_, NA_integer_, NA_integer_)), class = c("POSIXlt", 
      "POSIXt"))), row.names = c(NA, -6L), class = "data.frame")
      
      df2 <- structure(list(time = structure(list(sec = c(0, 0, 0, 0, 0, 0
      ), min = c(0L, 10L, 20L, 30L, 40L, 50L), hour = c(6L, 6L, 6L, 
      6L, 6L, 6L), mday = c(11L, 11L, 11L, 11L, 11L, 11L), mon = c(11L, 
      11L, 11L, 11L, 11L, 11L), year = c(119L, 119L, 119L, 119L, 119L, 
      119L), wday = c(3L, 3L, 3L, 3L, 3L, 3L), yday = c(344L, 344L, 
      344L, 344L, 344L, 344L), isdst = c(0L, 0L, 0L, 0L, 0L, 0L), zone = c("CET", 
      "CET", "CET", "CET", "CET", "CET"), gmtoff = c(NA_integer_, NA_integer_, 
      NA_integer_, NA_integer_, NA_integer_, NA_integer_)), class = c("POSIXlt", 
      "POSIXt")), Temp.ar = c(14.79, 14.74, 14.9, 15.14, 15.32, 15.6
      ), Ur.ar = c(78.5, 78.9, 78.9, 78.6, 77.8, 76.5), Vel.Vento = c(1.147, 
      1.045, 1.009, 1.076, 1.332, 1.216)), row.names = c(NA, -6L), class = "data.frame")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多