【问题标题】:Matching data from one dataframe to a time block that it fits within in a second dataframe将一个数据帧中的数据匹配到适合第二个数据帧的时间块
【发布时间】:2013-06-23 16:47:06
【问题描述】:

我有两个数据集,我想根据日期时间信息进行匹配。数据集 1 中的日期时间值表示以给定时间戳结束的 10 分钟时间块。我想将数据集 2 中的每一行与数据集 1 中的 10 分钟时间块(和相关数据)进行匹配。数据示例如下:

Dataset 1
datetime            count
10/11/2012 16:25    231
10/11/2012 16:35    55
10/11/2012 16:45    0
10/11/2012 16:55    30
10/11/2012 17:05    22
10/11/2012 17:15    431
10/11/2012 17:25    455
10/11/2012 17:35    560
10/11/2012 17:45    7
10/11/2012 17:55    36
10/11/2012 18:05    12
10/11/2012 18:15    144
10/11/2012 18:25    583

Dataset 2
datetime            a       n   dpm
10/11/2012 16:26    2.03    27  3473
10/11/2012 17:24    1.35    28  3636
10/11/2012 18:21    7.63    29  3516

我想最终得到这样的东西:

datetime2           a       n   dpm     datetime1           count
10/11/2012 16:26    2.03    27  3473    10/11/2012 16:35    55
10/11/2012 17:24    1.35    28  3636    10/11/2012 17:25    455
10/11/2012 18:21    7.63    29  3516    10/11/2012 18:25    583

我知道有诸如 cbind()、rbind() 和 merge() 之类的函数可用于合并数据集(基于我过去提出的一个相关问题:How to merge two data frames in r by a common column with mismatched date/time values),但我一直无法编写在这种情况下有帮助的代码。我尝试了 cbind(round(data, “mins”)) 和 cbind(trun(data, “hours”)) 的各种组合,但这些函数似乎匹配从数据集 1 到数据集 2 的每一行的多个时间块,而不是不仅仅是每行所在的块。我已经尝试了几个小时来找到一些可以解决这个问题的条件规则,但是没有运气。任何帮助将不胜感激。

【问题讨论】:

    标签: r datetime merge


    【解决方案1】:

    一种选择是使用data.table 的流行连接,也称为 并将最后一次观察结转 (locf)。

    library(data.table)
    DT  <- data.table(dataset1,key='datetime')
    DT1 <- data.table(dataset2,key='datetime')
    DT[DT1,roll='nearest']
                 datetime count    a  n  dpm
    1: 2012-11-10 16:26:00   231 2.03 27 3473
    2: 2012-11-10 17:24:00   455 1.35 28 3636
    3: 2012-11-10 18:21:00   583 7.63 29 3516
    

    编辑

    您可以在此处读取数据。通常我使用zoo 包和read.zoo 或者一个技巧是添加一个新的列名,如上:

    dat1 <- read.table(text='date time            a       n   dpm
    10/11/2012 16:26    2.03    27  3473
    10/11/2012 17:24    1.35    28  3636
    10/11/2012 18:21    7.63    29  3516',header=TRUE)
    
    dat1$datetime <- as.POSIXct(paste0(dat1$date,dat1$time),
                              format='%d/%m/%Y %H:%M')
         a  n  dpm            datetime
    1 2.03 27 3473 2012-11-10 16:26:00
    2 1.35 28 3636 2012-11-10 17:24:00
    3 7.63 29 3516 2012-11-10 18:21:00
    

    【讨论】:

    • 感谢您的评论。我已经尝试使用上面的代码,但是在使用 roll="nearest" 时我只收到以下错误消息:Error in [.data.frame(DT, DT1, roll = "nearest") : unused argument(s) (roll = "nearest").有什么想法吗?
    • @Emily 你应该使用data.table 而不是data.frame。您显示的错误消息是 [.data.frame`(DT, DT1, roll = "nearest")。
    • 抱歉,但我对 R 比较陌生!我认为您的代码的前两行将我的 data.frames(带有 POSIXt 类数据时间列)转换为 data.tables。我现在已经使用 dat1
    • @Emily 只需使用as.POSIXct 将您的POSIXlt 列转换为POSIXct。在将数据框转换为数据表之前执行此操作。
    • POSIXlt 是一个列表。您应该使用数字的 POSIXct(使用 mode 来检查它)。除了@HongOoi 评论,我在我的编辑中展示了如何将日期时间强制为 POSIXct。
    【解决方案2】:

    这样的?

    findRow <- function(dt, df) { min(which(df$datetime > dt )) }
    rows <- sapply(df2$datetime, findRow, df=df1)
    res <- cbind(df2, df1[rows,])
    
               datetime    a  n  dpm         datetime count
    2  10/11/2012 16:26 2.03 27 3473 10/11/2012 16:35    55
    7  10/11/2012 17:24 1.35 28 3636 10/11/2012 17:25   455
    13 10/11/2012 18:21 7.63 29 3516 10/11/2012 18:25   583
    

    PS1:我认为第 1 行的预期结果计数错误

    PS2:如果您以直接可用的方式提供数据集,那会更容易 形式。 我必须这样做:

    d1 <- 
    'datetime            count
    10/11/2012 16:25    231
    ...
    '
    d2 <- 
    'datetime            a       n   dpm
    10/11/2012 16:26    2.03    27  3473
    10/11/2012 17:24    1.35    28  3636
    10/11/2012 18:21    7.63    29  3516
    '
    
    .parse <- function(s) {
        cs <- gsub('\\s\\s+', '\t', s)
        read.table(text=cs, sep="\t", header=TRUE, stringsAsFactors=FALSE)
    }
    
    df1 <- .parse(d1)
    df2 <- .parse(d2)
    

    【讨论】:

    • 我编辑我的答案以展示一种无需正则表达式即可读取数据的方法。 +1。
    • @Karl:感谢您的解决方案!它运行良好,并为我提供了一个包含两组日期时间的输出数据框。将来我会尝试以更有用的形式提供数据。
    猜你喜欢
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2021-04-26
    • 2021-05-12
    • 2018-04-28
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多