我看到了在列之间使用lapply的示例,但没有人考虑(1)时间戳(2)基于时间戳的组(3)检测值何时更改
我正在寻找一种方法来对每个Panels
Sensor
,Panel 3
等任意数量的Panel 4
执行以下操作:
year
,month
,hour
,我正在寻找sum
和Counts Turn On
,它们是数值的#倍从0变为非零数字。为简化起见,hour
开头的非零值不应计入该值(即使前一个值为0)也是如此。 使用df
:
cols <- c("Timestamp","1000 Sensor 2 Panel 1","1000 Sensor 2 Panel 2")
tstmp <- seq(as.POSIXct("2018-08-13 00:00:00", tz="US/Eastern"),
as.POSIXct("2018-08-13 03:30:00", tz="US/Eastern"),
by="15 min") %>% as.data.frame()
stage1 <- c(rep(c(0,.7,1),5)) %>% as.data.frame()
stage2 <- c(0,1,rep(c(0,.5),5),0,1,1) %>% as.data.frame()
df = cbind(tstmp,stage1,stage2)
colnames(df) = cols
我希望结果为results_1
:
ID Year Month Hour Sum Count Turn On
1000 Sensor 2 Panel 1 2018 8 0 1.7 1
1000 Sensor 2 Panel 1 2018 8 1 2.4 1
1000 Sensor 2 Panel 1 2018 8 2 2.7 1
1000 Sensor 2 Panel 1 2018 8 3 1.7 1
1000 Sensor 2 Panel 2 2018 8 0 1.5 2
1000 Sensor 2 Panel 2 2018 8 1 1 2
1000 Sensor 2 Panel 2 2018 8 2 1 2
1000 Sensor 2 Panel 2 2018 8 3 2 1
对于更具野心的人,我希望看到一个解决方案,该解决方案能够确定前一小时的最后一个读数是否为0,而下一个小时的第一个读数是否为非零,并能够对其进行计数朝Count Turns On
迈进–解决方案如下图所示,results_advanced
:
ID Year Month Hour Sum Count Turn On
1000 Sensor 2 Panel 1 2018 8 0 1.7 1
1000 Sensor 2 Panel 1 2018 8 1 2.4 2
1000 Sensor 2 Panel 1 2018 8 2 2.7 1
1000 Sensor 2 Panel 1 2018 8 3 1.7 1
1000 Sensor 2 Panel 2 2018 8 0 1.5 2
1000 Sensor 2 Panel 2 2018 8 1 1 2
1000 Sensor 2 Panel 2 2018 8 2 1 2
1000 Sensor 2 Panel 2 2018 8 3 2 1
我希望至少有一个results_1
的解决方案,但希望为results_1
和results_advanced
都提供解决方案。请提供您有关思考过程的任何详细信息,这将帮助我(和其他人)了解更多信息。
我相信同时有data.table
和dplyr
解决方案,因此我将同时对其进行标记。
答案 0 :(得分:1)
这是第一个问题的tidyverse
方法。希望您可以使用它来解决问题的第二部分。
首先,我们将wide to long中的数据与gather
中的tidyr
进行转换。我还删除了Timestamp变量,但这是可选的。
library(lubridate); library(tidyverse)
df_long <- df %>%
gather(ID, Val, -Timestamp)
head(df_long)
Timestamp ID Val
1 2018-08-13 00:00:00 1000 Sensor 2 Panel 1 0.0
2 2018-08-13 00:15:00 1000 Sensor 2 Panel 1 0.7
3 2018-08-13 00:30:00 1000 Sensor 2 Panel 1 1.0
4 2018-08-13 00:45:00 1000 Sensor 2 Panel 1 0.0
5 2018-08-13 01:00:00 1000 Sensor 2 Panel 1 0.7
6 2018-08-13 01:15:00 1000 Sensor 2 Panel 1 1.0
df_long <- df_long %>%
mutate(Year = year(Timestamp),
Month = month(Timestamp),
Hour = hour(Timestamp)) %>%
select(-Timestamp)
然后我使用dplyr::group_by
和dplyr::lag
计算打开次数,这使您可以访问以前的值。
df_long <- df_long %>%
group_by(ID, Year, Month, Hour) %>%
mutate(Turned = ifelse(lag(Val) == 0 & Val != 0, 1, 0))
然后仅使用dplyr::summarise
计算最终值。注意,由于我们已经分组了,所以这部分的group_by
语句是多余的,但是为了清楚起见,我将其保留在其中。
df_long %>%
group_by(ID, Year, Month, Hour) %>%
summarise(Sum = sum(Val),
NTurned = sum(Turned, na.rm = T))
ID Year Month Hour Sum NTurned
<chr> <dbl> <dbl> <int> <dbl> <dbl>
1 1000 Sensor 2 Panel 1 2018 8 0 1.7 1
2 1000 Sensor 2 Panel 1 2018 8 1 2.4 1
3 1000 Sensor 2 Panel 1 2018 8 2 2.7 1
4 1000 Sensor 2 Panel 1 2018 8 3 1.7 1
5 1000 Sensor 2 Panel 2 2018 8 0 1.5 2
6 1000 Sensor 2 Panel 2 2018 8 1 1 2
7 1000 Sensor 2 Panel 2 2018 8 2 1 2
8 1000 Sensor 2 Panel 2 2018 8 3 2 1