在R中有条件地创建列

时间:2015-04-13 09:47:46

标签: r

在阅读了很多关于此的帖子并尝试我的数据解决方案后,我仍然没有得到理想的结果。基本上我有一个data.frame,其中包含两个时间列:TimeStampStartTime以及一个充当事件标识符的列: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

我尝试了ifelsesapply之类的内容。它没有真正起作用。我到目前为止的解决方案是提取所有非事件(ID == -999)。然后使用另一个ID变量标识所有唯一事件/非事件aggregate,以查找具有TimeStamp函数的第一个min。然后我有两个不同的Time列,我使用此post中的解决方案加入。 它有效,但我认为有更优雅和直接的方法来做到这一点。但作为一个R-newbie,我还不能解决它。

有什么建议吗?

顺便说一句:我希望它有点清楚,请告诉我它是不是。

编辑:我不认为我的问题是重复的,因为这些答案在我的案例中不起作用。它并没有解决我上面试图解释的额外复杂性。

1 个答案:

答案 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