Найти разрыв между непоследовательными наблюдениями - PullRequest
0 голосов
/ 06 мая 2019

Предположим, у меня есть следующая 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 и т. Д ...

Есть предложения?

Ответы [ 6 ]

4 голосов
/ 06 мая 2019

Мы можем принять разницу между всеми значениями, но сохранить только те значения, которые не являются последовательными

with(df, diff(x)[diff(x) != 1])
#[1]  2  2  2  3  4  2  2  2 15 10  4 15 29
2 голосов
/ 06 мая 2019

Используя 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

ПРИМЕЧАНИЕ: не повторять вычисления дважды

2 голосов
/ 06 мая 2019

Адаптируя подход @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
1 голос
/ 06 мая 2019

Вот еще один ответ, который добавляет разницу к 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
1 голос
/ 06 мая 2019

В основном вам нужно создать свою группирующую переменную и взять ее оттуда, то есть

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)
1 голос
/ 06 мая 2019

Сделайте вычитание следующим образом:

 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
...