【问题标题】:Identifying type of change in continuous values - R识别连续值变化的类型 - R
【发布时间】:2020-12-17 16:31:07
【问题描述】:

我有一个数据集,可以跟踪不同类型对象随时间的数值变化。所以我有 ID、度量、年月和变化的列。与之前的值相比,更改列对于发生的更改具有 TRUE 值。除非发生其他更改,否则该值之前和之后的任何常量都标记为 FALSE。

我希望能够做到以下几点:

  1. 能够设置阈值。因此,标记任何超过特定数字的价值案例。例如,如果阈值为 5,则标记高于或低于该阈值的任何情况,但不标记仅从 2 变为 4 的情况。

  2. 创建一个值变化的列。例如,-2 表示从 5 减少到 3,2 表示从 5 增加到 7。

           # <chr> <int>     <int>   <lgl> 
         # 1   A     2        2019-2 FALSE 
         # 2   A     2        2019-3 FALSE 
         # 3   A     2        2019-4 FALSE 
         # 4   A     5        2019-5 TRUE  
         # 5   A     5        2019-5 FALSE 
         # 6   A     4        2019-8 TRUE 
         # 7   A     4        2019-9 TRUE 
         # 8   B     23       2019-5 FALSE 
         # 9   B     7        2019-9 TRUE  
         #10   B     7        2020-5 FALSE 
         # … with 11 more rows
    

【问题讨论】:

    标签: r change-tracking


    【解决方案1】:

    dplyr 解决方案允许您获取列中的更改量,并且还将创建一个逻辑列,如果在任一方向上超过阈值,您将在其中获得TRUE。例如,在第 4 行中,该值已从 2 增加到 5,因此已超过阈值。但是,在第 5 行,该值保持在 5,因此第 4 行和第 5 行之间没有超过阈值。当我们到达第 6 行时,该值已降至 4,低于阈值,因此我们得到 @987654323 @在这一行再次。

    为了清楚起见,我已将阈值设置为 4.5。

    library(dplyr)
    
    threshold <- 4.5
    
    df %>%
      group_by(group) %>%
      mutate(change_amount  = c(0, diff(value)),
             crossed_thresh = sign(lag(value - threshold)) !=
                              sign(value - threshold),
             crossed_thresh = ifelse(is.na(crossed_thresh), FALSE,
                                     crossed_thresh))
    #> # A tibble: 10 x 6
    #> # Groups:   group [2]
    #>    group value month  change change_amount crossed_thresh
    #>    <chr> <int> <chr>  <lgl>          <dbl> <lgl>         
    #>  1 A         2 2019-2 FALSE              0 FALSE         
    #>  2 A         2 2019-3 FALSE              0 FALSE         
    #>  3 A         2 2019-4 FALSE              0 FALSE         
    #>  4 A         5 2019-5 TRUE               3 TRUE          
    #>  5 A         5 2019-5 FALSE              0 FALSE         
    #>  6 A         4 2019-8 TRUE              -1 TRUE          
    #>  7 A         4 2019-9 TRUE               0 FALSE         
    #>  8 B        23 2019-5 FALSE              0 FALSE         
    #>  9 B         7 2019-9 TRUE             -16 FALSE         
    #> 10 B         7 2020-5 FALSE              0 FALSE
    

    数据

    df <- structure(list(group = c("A", "A", "A", "A", "A", "A", "A", "B", 
    "B", "B"), value = c(2L, 2L, 2L, 5L, 5L, 4L, 4L, 23L, 7L, 7L), 
        month = c("2019-2", "2019-3", "2019-4", "2019-5", "2019-5", 
        "2019-8", "2019-9", "2019-5", "2019-9", "2020-5"), change = c(FALSE, 
        FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE
        )), class = "data.frame", row.names = c(NA, -10L))
    
    df
    #>    group value  month change
    #> 1      A     2 2019-2  FALSE
    #> 2      A     2 2019-3  FALSE
    #> 3      A     2 2019-4  FALSE
    #> 4      A     5 2019-5   TRUE
    #> 5      A     5 2019-5  FALSE
    #> 6      A     4 2019-8   TRUE
    #> 7      A     4 2019-9   TRUE
    #> 8      B    23 2019-5  FALSE
    #> 9      B     7 2019-9   TRUE
    #> 10     B     7 2020-5  FALSE
    
    

    【讨论】:

    • 谢谢@AllanCameron
    【解决方案2】:

    data.table 库很有帮助,尤其是它的 shift 功能。

    #reproduction of dataset
    df <- data.table(col1 = c('A','A','A','A','A','A','A','A','A','A'),
               col2 = c(2,2,2,5,5,4,4,23,7,7))
    

    添加两列

    首先我们检查行是否与前一行相同

    df[,Identical :=(col2 == shift(col2)) ]
    

    第二次我们将价值差异添加到前一个

    df[,change := col2 - shift(col2, 1)]
    

    它提供所需的输出

        col1 col2 Identical change
     1:    A    2    NA     NA
     2:    A    2  TRUE      0
     3:    A    2  TRUE      0
     4:    A    5 FALSE      3
     5:    A    5  TRUE      0
     6:    A    4 FALSE     -1
     7:    A    4  TRUE      0
     8:    A   23 FALSE     19
     9:    A    7 FALSE    -16
    10:    A    7  TRUE      0
    

    【讨论】:

      猜你喜欢
      • 2018-11-26
      • 2021-09-27
      • 2019-02-05
      • 2023-04-10
      • 2020-05-11
      • 1970-01-01
      • 2023-01-09
      • 2021-06-05
      • 2023-04-06
      相关资源
      最近更新 更多