Изменения суммы и количества в группе для каждого столбца в R - PullRequest
0 голосов
/ 14 декабря 2018

Я видел примеры использования 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.Пожалуйста, предоставьте любую подробную информацию о вашем мыслительном процессе, и это поможет мне (и другим) узнать больше.

Я считаю, что есть решения как 1037 *, так и dplyr, поэтому я буду отмечать оба.

1 Ответ

0 голосов
/ 14 декабря 2018

Это tidyverse подход к первой проблеме.Надеемся, что вы можете использовать это, чтобы приблизиться ко второй части вашего вопроса.

Сначала мы преобразуем данные из в длинную с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...