我有一个非常简单的问题,显然没有一个非常简单的解决方案。假设我有以下数据:
> 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
RcppRoll
和dplyr
lag()
lead()
spread
和myFunction(...iterableObj);
包中的函数的方法,以及所谓的整洁解决方案功能,但没有Heureka!迄今。由于我的数据集包含数十万行(以及更多列),因此非常不希望进行手动校正。
任何帮助表示赞赏!即使它只是指向现有的问题......
p.s。:显示 tidyverse 解决方案的奖励积分,因为我打算在管道工作流程中使用它。
编辑:感谢您的解决方案,他们都完美无缺!让我的一天:)
答案 0 :(得分:2)
lead
和lag
肯定是一种方法。
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)
另一种基于lag
和lead
的简单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