首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >识别连续值变化的类型-R

识别连续值变化的类型-R
EN

Stack Overflow用户
提问于 2020-12-17 16:31:07
回答 2查看 73关注 0票数 1

我有一个数据集,它可以跟踪不同类型对象的数值变化。因此,我有ID、度量值、月份和更改的列。change列具有与其上一个值相比发生的更改的真值。该值前后的任何常量都标记为FALSE,除非发生另一项更改。

我想做以下几件事:

  1. 能够设置阈值。因此,标记任何通过特定数字切换的值大小写。例如,如果阈值为5,则标记高于该阈值或低于该阈值的任何情况,但不标记仅从2更改为4的情况。

  1. 创建一个值更改的列。例如,-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

EN

回答 2

Stack Overflow用户

发布于 2020-12-17 16:45:04

dplyr解决方案允许您获取列中的更改量,并且还将创建一个逻辑列,在该列中,如果在两个方向上交叉阈值,则将获得TRUE。例如,在第4行中,该值从2增加到5,因此已经跨越了阈值。然而,在第5行中,值保持在5,因此在第4行和第5行之间没有交叉阈值。当我们到达第6行时,该值下降到4,低于阈值,因此我们再次在该行中获得TRUE

为了清晰起见,我已将门槛设为4.5。

代码语言:javascript
运行
复制
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

数据

代码语言:javascript
运行
复制
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
票数 1
EN

Stack Overflow用户

发布于 2020-12-17 17:20:50

data.table库可以提供帮助,特别是它的shift函数。

代码语言:javascript
运行
复制
#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))

添加两列

第一,我们检查行是否与前一行相同。

代码语言:javascript
运行
复制
df[,Identical :=(col2 == shift(col2)) ]

第二,将价值差异加到前一个。

代码语言:javascript
运行
复制
df[,change := col2 - shift(col2, 1)]

它提供了期望的输出。

代码语言:javascript
运行
复制
    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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65344638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档