使用逻辑运算符比较 R 中两列不等长
Compare two columns of Unequal Length in R using logical Operator
我正在处理一个大的时间序列数据集,我想比较两列
所以我的第一个专栏看起来像
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
如果需要更多详细信息,请告诉我
这是一个解决方案,只有一个 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
我正在处理一个大的时间序列数据集,我想比较两列 所以我的第一个专栏看起来像
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
如果需要更多详细信息,请告诉我
这是一个解决方案,只有一个 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