【问题标题】:How to compute running sum conditional on TRUE & FALSE如何计算 TRUE & FALSE 条件下的运行总和
【发布时间】:2019-11-28 15:27:35
【问题描述】:

我正在尝试创建一个新列,它是基于 TRUE 和 FALSE 列的条件差异。如果滞后 1 行是 FALSE,那么我们应该计算与开始或最后一个 TRUE 行的差异,以数据帧中较晚者为准,但是如果滞后 1 行是 TRUE,则应该重置差异。

我想尽可能多地使用 dplyr::mutate 函数。我正在尝试将 dplyr::lag 与 ifelse() 一起使用,但我很难适应这些条件

 dat <- data.frame(logic_col = c(F, F, T, T, F, F, F, T, F),
                   time_col = c(200, 435, 567, 895, 1012, 1345, 1456, 1700, 1900),
                   expected_col_unseen = c(200, 435, 567, 328, 117, 450, 561, 805, 200))

【问题讨论】:

  • expected 列与“累计和”不一致。由于第 2 行是错误的,因此预期的第 3 行应该是200+435+567=1202,而不是您所拥有的 1002。从那里开始,您的预期列似乎甚至没有接近,因为第 3 行是正确的,所以第 4 行应该是 895。我认为您可能正在尝试从预期中减去前一行的 time_col,但即便如此,累积总和不能正确结转。您能否修复您的预期数据或扩展您的计算方式?
  • 感谢您指出这一点。我将问题改写为更准确,我不是要进行累积总和,而是要计算差异。从最后一个 {TRUE} 值开始。
  • 我同意你的第 1-5 行,但是由于第 5-6 行都是错误的,所以第 6 行不应该等于第 6 行 time_col 吗?
  • 次要细节,但如果你使用dplyr,我鼓励使用dplyr::if_else(副基地ifelse),因为它可以防止常见错误(保护你自己,所以说话)。

标签: r dplyr


【解决方案1】:

我们可以使用tidyrdplyr 来做这样的事情:

library(dplyr)
library(tidyr)

dat %>% 
  mutate(tmp = lag(logic_col * time_col),
         tmp = ifelse(tmp==0, NA,tmp)) %>% 
  tidyr::fill(tmp, .direction = c("down")) %>% 
  mutate(out = time_col - ifelse(is.na(tmp), 0,tmp)) %>% 
  select(-tmp)

#>   logic_col time_col expected_col_unseen out
#> 1     FALSE      200                 200 200
#> 2     FALSE      435                 435 435
#> 3      TRUE      567                 567 567
#> 4      TRUE      895                 328 328
#> 5     FALSE     1012                 117 117
#> 6     FALSE     1345                 450 450
#> 7     FALSE     1456                 561 561
#> 8      TRUE     1700                 805 805
#> 9     FALSE     1900                 200 200

【讨论】:

    【解决方案2】:

    我会把它扔在那里,以防手动计算它只是令人困惑的事情:

    library(dplyr)
    dat %>%
      group_by(grp = cumsum(lag(!logic_col, default=FALSE))) %>%
      mutate(out = c(time_col[1], diff(time_col))) %>%
      ungroup()
    # # A tibble: 9 x 5
    #   logic_col time_col expected_col_unseen   grp   out
    #   <lgl>        <dbl>               <dbl> <int> <dbl>
    # 1 FALSE          200                 200     0   200
    # 2 FALSE          435                 435     1   435
    # 3 TRUE           567                 567     2   567
    # 4 TRUE           895                 328     2   328
    # 5 FALSE         1012                 117     2   117
    # 6 FALSE         1345                 450     3  1345
    # 7 FALSE         1456                 561     4  1456
    # 8 TRUE          1700                 805     5  1700
    # 9 FALSE         1900                 200     5   200
    

    【讨论】:

    • dat %&gt;% mutate(out = time_col - lag(logic_col * time_col, default = 0)) 你可以用这个来实现你所拥有的,但这不是 OP 所寻求的。
    • 好的,我知道你在做什么,这是一个简洁的捷径。我会坚持使用group_by,以防出现更复杂的计算。我不同意这不是“预期”列中的内容,但是该列与问题文本之间再次存在足够的不一致。 *耸耸肩*
    • 对不起,我也很困惑。我在问题数据集中的内容是正确的。这个问题的背景是我试图计算某个部件在机器中运行了多长时间。该零件不时更换(logic_col = T),所以我想知道某个零件在机器中的使用时间。
    猜你喜欢
    • 2021-03-24
    • 2020-12-10
    • 2020-08-24
    • 1970-01-01
    • 2021-08-31
    • 2011-03-10
    • 2019-03-20
    • 2011-07-09
    • 2020-04-09
    相关资源
    最近更新 更多