【问题标题】:Performing operations with lag on a dataframe to calculate a new value in R [duplicate]在数据帧上执行滞后操作以计算 R 中的新值 [重复]
【发布时间】:2020-07-23 20:54:04
【问题描述】:

我有以下代码,我正在计算数据点的百分比增长,然后我计算百分比增长的变化,我正在寻找的是能够添加一个列来计算读数的数量其中百分比增长变化为负

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

而我需要的是

   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

【问题讨论】:

    标签: r dataframe lag dplyr


    【解决方案1】:

    我们可以使用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))
    

    【讨论】:

    • 谢谢,效果很好,我现在在 R 中学习了一个新功能
    【解决方案2】:

    一种方法:首先定义一个分组变量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_change为负数,则将pct_growth_streak设置为组内的行号。

    df %>% 
    group_by(sgrp) %>% 
    mutate(pct_growth_streak = 
        (pct_growth_change < 0) * row_number()
    ) %>%
    ungroup() %>%
    select(-sgrp);
    

    【讨论】:

      【解决方案3】:

      我使用了这篇文章中的逻辑 (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))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-14
        • 2021-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-10
        • 2021-08-01
        相关资源
        最近更新 更多