【问题标题】:How to return the last matching condition row per group?如何返回每组的最后一个匹配条件行?
【发布时间】:2019-07-03 10:05:48
【问题描述】:

我正在处理一个包含许多机器的文件。每个机器都在一个周期内工作(从-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 个值的最后一行(高功率操作)。然后,我的目的是将最后一个高操作值到循环结束的长度相加。

期望的输出:

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

我怎样才能做到这一点?

【问题讨论】:

    标签: r group-by tail


    【解决方案1】:

    使用dplyr 的一种方法是filter 数据中的操作结束行,group_by Indxsum Operation2 值出现在Operation1 为 1 到最后一次出现之间最后一行。我们使用cumsum 值找到最后一次出现的 1。

    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
    

    或者找到最后一次出现的另一种方法是使用whichmax

    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))
    

    【讨论】:

    • 谢谢它似乎工作!但是我找不到 Oplength,它也不想变异。但是我可以在控制台上看到不错的 tibble... 你知道为什么吗?
    • @AliciaBassiere 也许您需要将结果分配回去? df1 &lt;- df %&gt;% filter(Operation1 != -1) %&gt;% group_by(Indx) %&gt;% summarise(Oplength = sum(Operation2[max(which(Operation1 == 1)) : n()])) 并立即查看 df1
    【解决方案2】:

    在基础 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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 2020-11-10
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      相关资源
      最近更新 更多