Как вернуть последнюю соответствующую строку условия для каждой группы? - PullRequest
1 голос
/ 03 июля 2019

Я работаю над файлом со многими машинами. Каждая машина работает в течение цикла (который идет от -1 до -1), и у меня есть некоторые параметры работы:

1: работа на высокой мощности 0,5: работа на малой мощности 0: нет операции -1: конец операции

У меня есть список моих машин, состоящий из такого типа фрейма данных (по одному на машину - это очень маленький образец):

    *Indx*  *N°1 Operation*  *N°1 Operation length*
       1           1                450
       1          0.5                84
       1           0                 48
       1           1                  4
       1          0.5                 4
       1           1                123
       1          0.5                14
       1          -1                 45
       2           1                471
       2           0                 47
       2          0.5                44
       2           0                145
       2          0.5                78
       2           1                 71
       2          0.5                19
       2           0                  2
       2          -1                 45

Я хотел бы получить для каждой группы последний ряд с 1 значением (операция с высокой мощностью). Моя цель состоит в том, чтобы суммировать длины от этого последнего значения операции High до конца цикла.

Желаемый вывод:

*Indx*    *N°1 Operation length*
  1                  123+14
  2                  71+19+2

Как мне добраться до этого?

Ответы [ 2 ]

2 голосов
/ 03 июля 2019

Использование dplyr в одну сторону - filter Строки окончания операций из данных, group_by Indx и sum значения Operation2, которые происходят между последним появлением, когда Operation1 равен 1 допоследний рядМы находим последнее вхождение 1, используя значение cumsum.

library(dplyr)

df %>%
  filter(Operation1 != -1) %>%
  group_by(Indx) %>%
  summarise(Oplength = sum(Operation2[cumsum(Operation1 == 1) == 
                                  max(cumsum(Operation1 == 1))]))

# A tibble: 2 x 2
#   Indx Oplength
#  <int>    <int>
#1     1      137
#2     2       92

Или другой способ найти последнее вхождение - использовать which и max

df %>%
  filter(Operation1 != -1) %>%
  group_by(Indx) %>%
  summarise(Oplength = sum(Operation2[max(which(Operation1 == 1)) : n()]))

данные

df <- structure(list(Indx = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L), Operation1 = c(1, 0.5, 0, 1, 0.5, 
1, 0.5, -1, 1, 0, 0.5, 0, 0.5, 1, 0.5, 0, -1), Operation2 = c(450L, 
84L, 48L, 4L, 4L, 123L, 14L, 45L, 471L, 47L, 44L, 145L, 78L, 
71L, 19L, 2L, 45L)), class = "data.frame", row.names = c(NA, -17L))
0 голосов
/ 03 июля 2019

В базе R мы могли бы сделать

do.call(rbind, by(d, d[[1]], function(x) 
  c(Indx=x[[1]][1], 
    N.1.Operation.length=sum(x[[3]][head(max(which(x[[2]] > .5)):nrow(x), -1)]))))
#   Indx N.1.Operation.length
# 1    1                  137
# 2    2                   92

данные

d <- structure(list(Indx = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L), N.1.Operation = c(1, 0.5, 0, 1, 
0.5, 1, 0.5, -1, 1, 0, 0.5, 0, 0.5, 1, 0.5, 0, -1), N.1.Operation.length = c(450L, 
84L, 48L, 4L, 4L, 123L, 14L, 45L, 471L, 47L, 44L, 145L, 78L, 
71L, 19L, 2L, 45L)), row.names = c(NA, -17L), class = "data.frame")
...