使用逻辑运算符比较R中的两列不等长

时间:2016-08-08 22:45:22

标签: time-series date-comparison

我正在处理一个大时间序列数据集,我想比较两列 所以我的第一个专栏看起来像

            timeperiod          timefortreatment
       2014-08-01 00:00:00        102.81818
       2014-08-01 01:00:00         12.34483
       2014-08-01 02:00:00         35.67568
       2014-08-01 03:00:00        125.57692
       2014-08-01 04:00:00         97.56250
       2014-08-01 05:00:00         36.66667

第二列看起来像

        arrivaltime         
       2014-08-01 00:14:00       
       2014-08-01 00:22:00         
       2014-08-01 00:47:00         
       2014-08-01 01:07:00        
       2014-08-01 01:19:00         
       2014-08-01 01:53:00 

两者长度不等,第二次大于第一次。我必须将第一列与第二列进行比较,得到最终的一列,如下所示。比较的逻辑是,如果第二列中的到达时间小于第一列中的条目(此处时间为1小时),则获得该特定时期的治疗时间值

             arrival          timefortreatment
       2014-08-01 00:14:00        102.81818
       2014-08-01 00:22:00        102.81818
       2014-08-01 00:47:00        102.81818
       2014-08-01 01:07:00         12.34483
       2014-08-01 01:19:00         12.34483
       2014-08-01 01:53:00         12.34483

我已经基于两个for循环创建了一个逻辑,它将永远占用50k +值:

for (i in 1:nrow(date)) 
{
    for (j in 1:nrow(period))
    { 
        if (date[i,1]>=period[j,])
        { 
            z[i,]=t[j,] 
            j=j+1
        } 
    } 
    i=i+1 
}

我想知道还有其他方法可以做到这一点。在这方面的任何帮助将受到高度赞赏。编辑我的答案以适应不同时间段的案例。

             timeperiod                  timefortreatment
              2014-08-01 00:14:00               75
              2014-08-01 00:19:00              143
              2014-08-01 00:44:00              126
              2014-08-01 01:04:00              125
              2014-08-01 01:19:00              125
              2014-08-01 01:49:00              122

对于这种情况,输出将如下所示基于相同的逻辑,即(到达> =时间段)

              arrival          timefortreatment
       2014-08-01 00:14:00            75
       2014-08-01 00:22:00           143
       2014-08-01 00:47:00           126
       2014-08-01 01:07:00           125
       2014-08-01 01:19:00           125
       2014-08-01 01:53:00           122 

如果需要更多详细信息,请告诉我

1 个答案:

答案 0 :(得分:1)

这是一个解决方案,只有一个for循环,存在更快的解决方案。

df1 = data.frame(timeperiod = seq(as.POSIXct("2014-08-01 00:00:00"), as.POSIXct("2014-08-01 05:00:00"), by = "1 hour"),
            timefortreatment = c(102.81818, 12.34483, 35.67568, 125.57692, 97.56250, 36.66667))
df2 = data.frame(arrivaltime = c(as.POSIXct("2014-08-01 00:14:00"), as.POSIXct("2014-08-01 00:22:00"), as.POSIXct("2014-08-01 00:47:00"), as.POSIXct("2014-08-01 01:07:00"), as.POSIXct("2014-08-01 01:19:00"), as.POSIXct("2014-08-01 01:53:00")))


library(stringr)
df2$time_min = as.POSIXct(paste0(str_sub(df2$arrivaltime, 1, 14), "00:00"))

for (i in 1:nrow(df2))
{
 df2$timefortreatment[i] = df1$timefortreatment[df1$timeperiod == df2$time_min[i]]
}

修改

在时间段内没有周期性,您可以使用difftime函数:

df1 = data.frame(timeperiod = c(as.POSIXct("2014-08-01 00:14:00"), as.POSIXct("2014-08-01 00:19:00"), as.POSIXct("2014-08-01 00:44:00"), as.POSIXct("2014-08-01 01:04:00"), as.POSIXct("2014-08-01 01:19:00"), as.POSIXct("2014-08-01 01:49:00")), timefortreatment = c(75, 143, 126, 125, 125, 122))
df2 = data.frame(arrivaltime = c(as.POSIXct("2014-08-01 00:14:00"), as.POSIXct("2014-08-01 00:22:00"), as.POSIXct("2014-08-01 00:47:00"), as.POSIXct("2014-08-01 01:07:00"), as.POSIXct("2014-08-01 01:19:00"), as.POSIXct("2014-08-01 01:53:00")))

for (i in 1:nrow(df2))
{
  df2$timefortreatment[i] = df1$timefortreatment[which.min(abs(difftime(df2$arrivaltime[i], df1$timeperiod)))]
}


# APPLY solution 

my_function = function(value)
{
  output = df1$timefortreatment[which.min(abs(difftime(value, df1$timeperiod)))]
}
df2$timefortreatment = apply(df2, 1, my_function)


> df2
          arrivaltime timefortreatment
1 2014-08-01 00:14:00               75
2 2014-08-01 00:22:00              143
3 2014-08-01 00:47:00              126
4 2014-08-01 01:07:00              125
5 2014-08-01 01:19:00              125
6 2014-08-01 01:53:00              122