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

问题描述 投票:2回答:3

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

> 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

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

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

  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

注意第7天和第10天是如何被删除的,并且它们的计数已被添加到第6天和第9天。这确实是我后续数据分析所需的格式,这将受到“假”计数的影响。

我已经尝试过使用zooRcppRoll包中的函数的多个“移动/滚动窗口”方法,以及使用dplyrs lag()and lead()函数的所谓整洁解决方案,但没有Heureka!迄今。由于我的数据集包含数十万行(以及更多列),因此非常不希望进行手动校正。

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

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

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

r dataframe dplyr
3个回答
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

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

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
© www.soinside.com 2019 - 2024. All rights reserved.