我有一个数据集,它可以跟踪不同类型对象的数值变化。因此,我有ID、度量值、月份和更改的列。change列具有与其上一个值相比发生的更改的真值。该值前后的任何常量都标记为FALSE,除非发生另一项更改。
我想做以下几件事:
。
发布于 2020-12-17 16:45:04
此dplyr解决方案允许您获取列中的更改量,并且还将创建一个逻辑列,在该列中,如果在两个方向上交叉阈值,则将获得TRUE。例如,在第4行中,该值从2增加到5,因此已经跨越了阈值。然而,在第5行中,值保持在5,因此在第4行和第5行之间没有交叉阈值。当我们到达第6行时,该值下降到4,低于阈值,因此我们再次在该行中获得TRUE。
为了清晰起见,我已将门槛设为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发布于 2020-12-17 17:20:50
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 0https://stackoverflow.com/questions/65344638
复制相似问题