R 如何匹配两个时间列并在匹配时打印值?

R 如何匹配两个时间列并在匹配时打印值?,r,datetime,match,data.table,aggregate,R,Datetime,Match,Data.table,Aggregate,我在这里把头撞在墙上。希望有人能帮忙 我在R中有一个聚合数据帧(d1),带有一个时间列和一个带有二进制值的列。时间列没有统一的时间步长 d1: 我还有一个数据帧(d2),其中有一列具有统一的时间步长,因此d2中的行数比d1中的行数长 d2: 我想做的是在Time_理想值旁边打印设置值,其中d1和d2中两个时间列中的时间值分别匹配 我试过了 d1 <- data.table(d1, key = 'Time') d2 <- data.table(d2, key = 'Time_Ideal

我在这里把头撞在墙上。希望有人能帮忙

我在R中有一个聚合数据帧(d1),带有一个时间列和一个带有二进制值的列。时间列没有统一的时间步长

d1:

我还有一个数据帧(d2),其中有一列具有统一的时间步长,因此d2中的行数比d1中的行数长

d2:

我想做的是在Time_理想值旁边打印设置值,其中d1和d2中两个时间列中的时间值分别匹配

我试过了

d1 <- data.table(d1, key = 'Time')
d2 <- data.table(d2, key = 'Time_Ideal')

d2[d1, nomatch=0]
d2[d1]

d1可能不是最好的解决方案,但我认为它是有效的:

library(plyr)

d3 <- d2
colnames(d3) <- c("Time")

d4 <- join(d3, d1)

for(i in 2:length(d4$Set)){
  if(is.na(d4$Set[i])){
    d4$Set[i] <- d4$Set[i - 1]
  } 
}
库(plyr)
d3可能与dplyr有关

library(dplyr)

d2 %>%
  left_join(d1, by = c("Time_Ideal" = "Time"))
要填充集合的最后一个值,请使用:

library(dplyr)
library(zoo)

d2 %>%
  left_join(d1, by = c("Time_Ideal" = "Time")) %>%
  mutate(Set = na.locf(d3$Set, na.rm = FALSE))
测试: 输入数据 没有使用日期时间类型的提示。我在下面使用POSIXct:

d1 <- 
  structure(list(Time = structure(c(1420293300, 1420550400, 1420550700, 
  1420551000, 1420551300, 1420551600, 1420551900, 1420557000, 1420613100, 
  1420614000, 1420614300, 1420616700), class = c("POSIXct", "POSIXt"
  ), tzone = ""), 
  Set = c(0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 0L, 1L, 
  1L, 0L)), row.names = c(NA, -12L), .Names = c("Time", "Set"), 
  class = "data.frame")

d2 <- 
  structure(list(Time_Ideal = structure(c(1420808700, 1420809000, 
  1420809300, 1420809600, 1420809900, 1420810200, 1420810500, 1420810800, 
  1420811100, 1420811400), class = c("POSIXct", "POSIXt"
  ), tzone = "")), row.names = c(NA, -10L), .Names = "Time_Ideal", 
  class = "data.frame")
执行连接#2(已更正的输入数据) 未来3天的d1班次:

d1$Time <- d1$Time + 3600*24*3 # three days shift

下面是解决这个问题的
data.table
方法(因为这是实际问题)。使用@bergant提供的修改数据(因为OP数据集不匹配),只需执行以下操作:

setkey(setDT(d1), Time) # `d2` doesn't have to be a `data.table`
d1[d2] # you can set `, nomatch = 0L` if you want to remove non-matches
#                    Time Set
#  1: 2015-01-09 15:05:00  NA
#  2: 2015-01-09 15:10:00  NA
#  3: 2015-01-09 15:15:00  NA
#  4: 2015-01-09 15:20:00   1
#  5: 2015-01-09 15:25:00   1
#  6: 2015-01-09 15:30:00   1
#  7: 2015-01-09 15:35:00   1
#  8: 2015-01-09 15:40:00   1
#  9: 2015-01-09 15:45:00   0
# 10: 2015-01-09 15:50:00  NA

另一种方法(更好)是通过引用修改
d2
。您必须先将
d2
转换为
数据。表
转换为数据

setkey(setDT(d2), Time_Ideal)
d2[d1, Set := i.Set][] # `d2` was modified by reference.
#                    Time Set
#  1: 2015-01-09 15:05:00  NA
#  2: 2015-01-09 15:10:00  NA
#  3: 2015-01-09 15:15:00  NA
#  4: 2015-01-09 15:20:00   1
#  5: 2015-01-09 15:25:00   1
#  6: 2015-01-09 15:30:00   1
#  7: 2015-01-09 15:35:00   1
#  8: 2015-01-09 15:40:00   1
#  9: 2015-01-09 15:45:00   0
# 10: 2015-01-09 15:50:00  NA

当给定时间内没有设置值时,我想打印上面一行中的设置值。使用
dput
提供数据,它将更容易复制。另外,准确的预期输出也会很好。我从你的问题中了解到,你得到的列名与你预期的不同。提供的两个文件之间没有匹配的时间戳,请显示你想要的结果好吗?它应该像
setkey(setDT(d1),Time)一样简单;d1[d2]
我用3天的d1$时间轮班测试了我的答案(见“测试”部分)谢谢!第一个例子奏效了。不幸的是,(更好的)没有。但现在我只需要用上面的值替换NA值…到底什么不起作用?你犯了什么错误?另外,你所说的“替换为上面的值”是什么意思?我的意思是:在上面的第9行中有一个0。第10排有一个NA。我希望NA变为0(等于第9行中的值=上面的值)。等这有意义吗?我目前正在试验for.loop和if语句,但还没有成功。我得到的错误消息是:“In
[.data.table
(d2,d1,
:=
(Set,I.Set)):强制将'double'RHS设置为'integer'以匹配列的类型;可能具有截断的精度。请先将目标列更改为'double'(通过创建一个新的'double'向量长度9233(整个表的nrows)并指定该长度;即'replace'列),或强制RHS为'integer'(例如1L、NA|[real | integer]UAS.*等),以明确您的意图并提高速度。或者,请在创建表时预先正确设置列类型并坚持它。”没关系。你的第一个建议是完美。错误意味着你已经在
d2
中设置了
Set
列。你不应该拥有它。
d1$Time <- d1$Time + 3600*24*3 # three days shift
d2 %>%
  left_join(d1, by = c("Time_Ideal" = "Time"))

                Time_Ideal Set
    1  2015-01-09 14:05:00  NA
    2  2015-01-09 14:10:00  NA
    3  2015-01-09 14:15:00  NA
    4  2015-01-09 14:20:00   1
    5  2015-01-09 14:25:00   1
    6  2015-01-09 14:30:00   1
    7  2015-01-09 14:35:00   1
    8  2015-01-09 14:40:00   1
    9  2015-01-09 14:45:00   0
    10 2015-01-09 14:50:00  NA      
setkey(setDT(d1), Time) # `d2` doesn't have to be a `data.table`
d1[d2] # you can set `, nomatch = 0L` if you want to remove non-matches
#                    Time Set
#  1: 2015-01-09 15:05:00  NA
#  2: 2015-01-09 15:10:00  NA
#  3: 2015-01-09 15:15:00  NA
#  4: 2015-01-09 15:20:00   1
#  5: 2015-01-09 15:25:00   1
#  6: 2015-01-09 15:30:00   1
#  7: 2015-01-09 15:35:00   1
#  8: 2015-01-09 15:40:00   1
#  9: 2015-01-09 15:45:00   0
# 10: 2015-01-09 15:50:00  NA
setkey(setDT(d2), Time_Ideal)
d2[d1, Set := i.Set][] # `d2` was modified by reference.
#                    Time Set
#  1: 2015-01-09 15:05:00  NA
#  2: 2015-01-09 15:10:00  NA
#  3: 2015-01-09 15:15:00  NA
#  4: 2015-01-09 15:20:00   1
#  5: 2015-01-09 15:25:00   1
#  6: 2015-01-09 15:30:00   1
#  7: 2015-01-09 15:35:00   1
#  8: 2015-01-09 15:40:00   1
#  9: 2015-01-09 15:45:00   0
# 10: 2015-01-09 15:50:00  NA