R 如何匹配两个时间列并在匹配时打印值?
我在这里把头撞在墙上。希望有人能帮忙 我在R中有一个聚合数据帧(d1),带有一个时间列和一个带有二进制值的列。时间列没有统一的时间步长 d1: 我还有一个数据帧(d2),其中有一列具有统一的时间步长,因此d2中的行数比d1中的行数长 d2: 我想做的是在Time_理想值旁边打印设置值,其中d1和d2中两个时间列中的时间值分别匹配 我试过了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
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