在阅读了很多关于此的帖子并尝试我的数据解决方案后,我仍然没有得到理想的结果。基本上我有一个data.frame
,其中包含两个时间列:TimeStamp
和StartTime
以及一个充当事件标识符的列:ID
。我想创建第三列,如果ID == -999
(表示非事件),则使用TimeStamp
列,否则应使用StartTime
。
更复杂一点:因此,数据代表'块'事件。在事件之间有时间没有什么'发生即ID == -999
。在这种情况下,我希望该列由该块的第一个元素填充。
以下是我数据的过度简化版本:
ID <- rep(c(84,-999,88),c(3,3,4))
f <- as.POSIXct("09:55:45", format = "%H:%M:%S")
t <- as.POSIXct("10:05:45", format = "%H:%M:%S")
TimeStamp <- seq.POSIXt(from = f, to = t, length.out = 10)
StartTime <- as.POSIXct(rep(c("09:54:12",NA,"10:02:25"),c(3,3,4)), format = "%H:%M:%S")
df <- data.frame(TimeStamp,StartTime,ID)
这是我想要的结果:
> df[,"Time"] <- rep(c("09:54","09:59","10:02"), c(3,3,4))
> df
# TimeStamp StartTime ID Time
#1 2015-04-13 09:55:45 2015-04-13 09:54:12 84 09:54
#2 2015-04-13 09:56:51 2015-04-13 09:54:12 84 09:54
#3 2015-04-13 09:57:58 2015-04-13 09:54:12 84 09:54
#4 2015-04-13 09:59:05 <NA> -999 09:59
#5 2015-04-13 10:00:11 <NA> -999 09:59
#6 2015-04-13 10:01:18 <NA> -999 09:59
#7 2015-04-13 10:02:25 2015-04-13 10:02:25 88 10:02
#8 2015-04-13 10:03:31 2015-04-13 10:02:25 88 10:02
#9 2015-04-13 10:04:38 2015-04-13 10:02:25 88 10:02
#10 2015-04-13 10:05:45 2015-04-13 10:02:25 88 10:02
我尝试了ifelse
和sapply
之类的内容。它没有真正起作用。我到目前为止的解决方案是提取所有非事件(ID == -999
)。然后使用另一个ID变量标识所有唯一事件/非事件aggregate
,以查找具有TimeStamp
函数的第一个min
。然后我有两个不同的Time
列,我使用此post中的解决方案加入。
它有效,但我认为有更优雅和直接的方法来做到这一点。但作为一个R-newbie,我还不能解决它。
有什么建议吗?
顺便说一句:我希望它有点清楚,请告诉我它是不是。编辑:我不认为我的问题是重复的,因为这些答案在我的案例中不起作用。它并没有解决我上面试图解释的额外复杂性。
答案 0 :(得分:4)
以下是使用data.table
v >= 1.9.5的可能解决方案(我在数据集的末尾添加了另一个-999
事件,因为据我所知,您希望对其进行区别对待)。
基本上我只是使用新的rleid
函数创建一个新索引(并将其直接插入到by
语句中),然后设置一个简单的if
else
声明
library(data.table)
setDT(df)[, Time := if(anyNA(StartTime)) {
format(TimeStamp[1L], "%H:%M")
} else {
format(StartTime[1L], "%H:%M")
},
by = rleid(ID)][]
# TimeStamp StartTime ID Time
# 1: 2015-04-13 09:55:45 2015-04-13 09:54:12 84 09:54
# 2: 2015-04-13 09:56:49 2015-04-13 09:54:12 84 09:54
# 3: 2015-04-13 09:57:54 2015-04-13 09:54:12 84 09:54
# 4: 2015-04-13 09:58:58 <NA> -999 09:58
# 5: 2015-04-13 10:00:03 <NA> -999 09:58
# 6: 2015-04-13 10:01:08 <NA> -999 09:58
# 7: 2015-04-13 10:02:12 2015-04-13 10:02:25 88 10:02
# 8: 2015-04-13 10:03:17 2015-04-13 10:02:25 88 10:02
# 9: 2015-04-13 10:04:21 2015-04-13 10:02:25 88 10:02
# 10: 2015-04-13 10:05:26 2015-04-13 10:02:25 88 10:02
# 11: 2015-04-13 10:06:31 <NA> -999 10:06
# 12: 2015-04-13 10:07:35 <NA> -999 10:06
# 13: 2015-04-13 10:08:40 <NA> -999 10:06
# 14: 2015-04-13 10:09:45 <NA> -999 10:06