我目前的数据包含一列日期和时间(已经是POSIXct格式)和一列显示数据记录器的“ON / OFF”状态。我需要计算OFF(0)和ON(1)状态之间经过的时间来计算延迟。
数据如下所示:
onoff datetime
1 1 2014-05-14 16:26:57
2 0 2014-05-14 16:27:02
3 1 2014-05-14 16:27:06
4 0 2014-05-14 16:27:12
5 1 2014-05-14 16:28:10
6 0 2014-05-14 16:28:15
我正在努力解决这个问题。在Excel中,我创建了一个if-then语句,在ON / OFF变量给定“0”条件的情况下从前一行中减去每一行。
我认为在R中执行此操作的最佳方法可能是创建2个新列,每个列对应于onoff = 1或0时的子集。我该怎么做?如果我可以创建两列,使用timediff函数计算会更容易(并且可以排除NA或非常大的值)。感谢您的帮助,我对此非常陌生,但未通过Google或其他帮助网站找到我的具体问题的答案。
答案 0 :(得分:2)
这些解决方案(3)特别短,并且还可以根据fill
变量的值灵活地将填充值指定为NA或0。
1)ave 根据海报的评论进行修改,以便为原始data.frame添加差异。 cumsum(onoff)
c(1, 1, 2, 2, ...)
为ave
而diff
会在每个群组中执行ave
一个与前两个transform(DF, elapsed = ave(as.numeric(datetime), cumsum(onoff), FUN = diff))
参数长度相同的向量。
onoff datetime elapsed
1 1 2014-05-14 16:26:57 5
2 0 2014-05-14 16:27:02 5
3 1 2014-05-14 16:27:06 6
4 0 2014-05-14 16:27:12 6
5 1 2014-05-14 16:28:10 5
6 0 2014-05-14 16:28:15 5
结果是:
library(dplyr)
DF %>%
mutate(grp = cumsum(onoff)) %>%
group_by(grp) %>%
mutate(elapsed = diff(as.numeric(datetime))) %>%
select(- grp)
2)dplyr 使用dplyr我们可以交替编写以下内容,它提供与上面类似的输出:
fill
2a)备用dplyr解决方案是。这允许我们将> fill <- NA
> DF %>% mutate(elapsed = as.numeric(datetime - lag(datetime)) * c(fill, 1))
onoff datetime elapsed
1 1 2014-05-14 16:26:57 NA
2 0 2014-05-14 16:27:02 5
3 1 2014-05-14 16:27:06 NA
4 0 2014-05-14 16:27:12 6
5 1 2014-05-14 16:28:10 NA
6 0 2014-05-14 16:28:15 5
值指定为NA或0:
diff
3)这只使用了普通fill
,与3a一起似乎是最简单的解决方案。使用上面的transform(DF, elapsed = c(fill, diff(as.numeric(datetime))) * c(fill, 1))
:
transform(DF, elapsed = c(0, diff(as.numeric(datetime))) * !onoff)
这给2a提供了类似的结果。
3a)除了填充零之外,这与最后一个相同。
transform(DF, elapsed = as.numeric(datetime - rep(datetime[onoff == 1], each=2)))
4)在此解决方案中,我们填0:
onoff datetime elapse
1 1 2014-05-14 16:26:57 0
2 0 2014-05-14 16:27:02 5
3 1 2014-05-14 16:27:06 0
4 0 2014-05-14 16:27:12 6
5 1 2014-05-14 16:28:10 0
6 0 2014-05-14 16:28:15 5
,并提供:
DF
5) @thelatemail在评论中提供了另一种选择。
下次请提供样本输出以澄清您的问题。
DF <- structure(list(onoff = c(1L, 0L, 1L, 0L, 1L, 0L),
datetime = structure(c(1400099217, 1400099222, 1400099226, 1400099232,
1400099290, 1400099295), class = c("POSIXct", "POSIXt"), tzone = "")),
.Names = c("onoff", "datetime"), row.names = c(NA, -6L), class = "data.frame")
是:
{{1}}
ADDED 几种替代解决方案。