我有以下代码,我要计算数据点的增长百分比,然后计算增长百分比的变化,我要寻找的是能够添加一列来计算读数的数量增长率变化为负的情况
_data
我得到的输出如下:
df <- data.frame(id = c(1,2,3,4,5,6,7,8,9,10,11,12), data = c(19, 19, 27, 27, 38, 42, 47, 48, 49, 50, 51, 53))
df <- mutate(df, pct_growth = (data - lag(data))/lag(data))
df <- mutate(df, pct_growth_change = pct_growth - lag(pct_growth))
df$pct_growth_streak <- 0
df <- dplyr::mutate(df, pct_growth_streak = ifelse(pct_growth_change <=0, lag(pct_growth_streak)+1,0) )
我需要的是
id data pct_growth pct_growth_change pct_growth_streak
1 1 19 NA NA NA
2 2 19 0.00000000 NA NA
3 3 27 0.42105263 0.4210526316 0
4 4 27 0.00000000 -0.4210526316 1
5 5 38 0.40740741 0.4074074074 0
6 6 42 0.10526316 -0.3021442495 1
7 7 47 0.11904762 0.0137844612 0
8 8 48 0.02127660 -0.0977710233 1
9 9 49 0.02083333 -0.0004432624 1
10 10 50 0.02040816 -0.0004251701 1
11 11 51 0.02000000 -0.0004081633 1
12 12 53 0.03921569 0.0192156863 0
答案 0 :(得分:4)
我们可以使用rleid
创建连续条纹的组并在其上计算cumsum
。
library(data.table)
setDT(df)[, pct_growth_streak := cumsum(pct_growth_streak),
rleid(pct_growth_streak)]
df
# id data pct_growth pct_growth_change pct_growth_streak
# 1: 1 19 NA NA NA
# 2: 2 19 0.00000000 NA NA
# 3: 3 27 0.42105263 0.4210526316 0
# 4: 4 27 0.00000000 -0.4210526316 1
# 5: 5 38 0.40740741 0.4074074074 0
# 6: 6 42 0.10526316 -0.3021442495 1
# 7: 7 47 0.11904762 0.0137844612 0
# 8: 8 48 0.02127660 -0.0977710233 1
# 9: 9 49 0.02083333 -0.0004432624 2
#10: 10 50 0.02040816 -0.0004251701 3
#11: 11 51 0.02000000 -0.0004081633 4
#12: 12 53 0.03921569 0.0192156863 0
我们也可以dplyr
使用它:
library(dplyr)
df %>%
group_by(grp = rleid(pct_growth_streak)) %>%
mutate(pct_growth_streak = cumsum(pct_growth_streak))
或使用ave
:
with(df, ave(pct_growth_streak, rleid(pct_growth_streak), FUN = cumsum))
答案 1 :(得分:1)
一种方法:首先定义一个分组变量sgrp
,该变量随pct_growth_change
的每个符号变化而递增:
df %<>% mutate(sgrp = cumsum(if_else(sign(pct_growth_change) ==
sign(lag(pct_growth_change, 1)), 0, 1, 1)))
然后按sgrp
分组,如果pct_growth_streak
为负,则将pct_growth_change
设置为组内的行号。
df %>%
group_by(sgrp) %>%
mutate(pct_growth_streak =
(pct_growth_change < 0) * row_number()
) %>%
ungroup() %>%
select(-sgrp);
答案 2 :(得分:1)
我使用了这篇帖子(https://stackoverflow.com/a/49051192/9203158)中的逻辑,感谢@missuse:
library(tidyverse)
library(data.table)
df %>%
mutate(pct_growth = (data - lag(data))/lag(data),
pct_growth_change = pct_growth - lag(pct_growth),
streak_change = ifelse(pct_growth_change > 0, -1, 1),
is_neg = ifelse(pct_growth_change < 0, 1, 0)) %>%
group_by(grp = rleid(streak_change)) %>%
mutate(pct_growth_streak = streak_change*cumsum(is_neg)) %>%
ungroup() %>%
select(-c(grp, streak_change, is_neg))