【发布时间】:2019-09-24 00:44:08
【问题描述】:
假设我有以下data.frame:
df = data.frame(x = c(1,3,5,6,8,11,15,16,18,20,21,22,24,25,40,50,54,55,70,71,100,101,102,103))
我需要找到非连续 x 值之间的滞后。 这意味着自动执行:3-1、5-3、8-6、11-8、15-11、18-16、20-18、24-22 等...
有什么建议吗?
【问题讨论】:
假设我有以下data.frame:
df = data.frame(x = c(1,3,5,6,8,11,15,16,18,20,21,22,24,25,40,50,54,55,70,71,100,101,102,103))
我需要找到非连续 x 值之间的滞后。 这意味着自动执行:3-1、5-3、8-6、11-8、15-11、18-16、20-18、24-22 等...
有什么建议吗?
【问题讨论】:
我们可以取所有值之间的差异,但只保留那些不连续的值
with(df, diff(x)[diff(x) != 1])
#[1] 2 2 2 3 4 2 2 2 15 10 4 15 29
【讨论】:
采用@Ronak Shah 的方法,我们可以使用dplyr 实现这一点,如下所示:
library(dplyr)
df %>%
transmute(x=lead(x,1)-x) %>%
filter(x!=1)
x
1 2
2 2
3 2
4 3
5 4
6 2
7 2
8 2
9 15
10 10
11 4
12 15
13 29
【讨论】:
使用head、tail 来获得差异。
with(df, {i1 <- tail(x, -1) - head(x, -1); i1[i1 != 1]})
#[1] 2 2 2 3 4 2 2 2 15 10 4 15 29
注意:不要重复计算两次
【讨论】:
您基本上需要构建分组变量并从那里获取它,即
c(FALSE, cumsum(diff(df$x) == 1))
#[1] 0 0 0 1 1 1 1 2 2 2 3 4 4 5 5 5 5 6 6 7 7 8 9 10
然后你可以用它来做任何你想做的计算,例如不同的是,
tapply(df$x, df$new, diff)
#$`0`
#[1] 2 2
#$`1`
#[1] 2 3 4
#$`2`
#[1] 2 2
#$`3`
#numeric(0)
#$`4`
#[1] 2
#$`5`
#[1] 15 10 4
#$`6`
#[1] 15
#$`7`
#[1] 29
#$`8`
#numeric(0)
#$`9`
#numeric(0)
#$`10`
#numeric(0)
【讨论】:
这是另一个答案,它将差异附加到 df 以及起始 x 值:
df = data.frame(x = c(1,3,5,6,8,11,15,16,18,20,21,22,24,25,40,50,54,55,70,71,100,101,102,103))
df$x0 <- c(NA_integer_, df[1:(nrow(df)-1), 'x'])
df$difference = c(0, diff(df$x))
df[df$difference > 1, ]
# x x0 difference
2 3 1 2
3 5 3 2
5 8 6 2
6 11 8 3
7 15 11 4
9 18 16 2
10 20 18 2
13 24 22 2
15 40 25 15
16 50 40 10
17 54 50 4
19 70 55 15
21 100 71 29
【讨论】:
像这样做减法:
df_lag <- df[2:nrow(df),] - df[1:(nrow(df)-1),]
这会给你想要的延迟。
df_lag[df_lag>1]
[1] 2 2 2 3 4 2 2 2 15 10 4 15 29
【讨论】: