条件下折叠行并在R中重新使用它们的值

时间:2018-03-05 14:16:46

标签: r dataframe dplyr

我有一个非常简单的问题,显然没有一个非常简单的解决方案。假设我有以下数据:

> test <- data.frame(Day = c(1:10), Counts = c(0, 0, 6, 0, 0, 5, 1, 0, 3, 4))
> test
   Day Counts
1    1      0
2    2      0
3    3      6
4    4      0
5    5      0
6    6      5
7    7      1
8    8      0
9    9      3
10  10      4

根据有关数据来源的知识,我可以放心地假设非零 Counts 在随后的日子里不会发生。相反,原始错过了一些 Counts 。例如, Day 6和7的 Counts 将属于 Day 6(总计6 Counts ) 。

我想找到一个可以产生所需输出的常规解决方案:

  Day Counts
1   1      0
2   2      0
3   3      6
4   4      0
5   5      0
6   6      6
7   8      0
8   9      7

注意 Day 7和10是如何被删除的, Counts 已添加到 Day 6和9的 Day 。这确实是我后续数据分析所需的格式,这些格式会受到&#34; false&#34; 计数

我已经尝试了多个&#34;移动/滚动窗口&#34;使用zoo RcppRolldplyr lag() lead() spreadmyFunction(...iterableObj); 包中的函数的方法,以及所谓的整洁解决方案功能,但没有Heureka!迄今。由于我的数据集包含数十万行(以及更多列),因此非常不希望进行手动校正。

任何帮助表示赞赏!即使它只是指向现有的问题......

p.s。:显示 tidyverse 解决方案的奖励积分,因为我打算在管道工作流程中使用它。

编辑:感谢您的解决方案,他们都完美无缺!让我的一天:)

3 个答案:

答案 0 :(得分:2)

leadlag肯定是一种方法。

test %>%
  mutate(lead1 = lead(Counts, 1), lag1 = lag(Counts)) %>% 
  mutate(Counts2 = if_else(Counts > 0, Counts + lead1, Counts)) %>% 
  filter(!(lag1 > 0 & Counts > 0))

代码可以缩短为

test %>%
  mutate(Counts = if_else(Counts > 0, Counts + lead(Counts, 1), Counts)) %>% 
  filter(!(lag(Counts) > 0 & Counts > 0))

  Day Counts
1   1      0
2   2      0
3   3      6
4   4      0
5   5      0
6   6      6
7   8      0
8   9      7

答案 1 :(得分:2)

另一种基于laglead的简单dplyr方法:

test %>%
  mutate(Counts = ifelse(Counts != 0 & lead(Counts) != 0,
                         Counts + lead(Counts), Counts)) %>%
  mutate(Counts = ifelse(Counts != 0 & lag(Counts) != 0, NA, Counts)) %>%
  na.omit()
  Day Counts
1   1      0
2   2      0
3   3      6
4   4      0
5   5      0
6   6      6
8   8      0
9   9      7

答案 2 :(得分:0)

1)这使用data.table包。首先将测试转换为data.table dt,然后使用rleid创建分组变量,为每次运行的零或非零创建一个组。对于每个这样的组,返回计数的总和,后跟尾随零:

library(data.table)
dt <- as.data.table(test)

dt[, Fix := c(sum(Counts), 0 * Counts[-1]), by = rleid(Counts > 0)]

,并提供:

> dt
    Day Counts Fix
 1:   1      0   0
 2:   2      0   0
 3:   3      6   6
 4:   4      0   0
 5:   5      0   0
 6:   6      5   6
 7:   7      1   0
 8:   8      0   0
 9:   9      3   7
10:  10      4   0

2)这使用dplyr和data.table中的rleid

library(dplyr)
library(data.table)

test %>%
     group_by(rleid(Counts > 0)) %>%
     mutate(Fix = c(sum(Counts), 0 * Counts[-1])) %>%
     ungroup