Расчет отрезков последовательных значений - PullRequest
1 голос
/ 16 мая 2019

У меня есть df с двумя интересующими колонками: дата и качество.Дата - это дневной временной ряд.Есть три варианта качества - Хороший, Оценочный, Отсутствующий.С одним из этих вариантов связан с определенной датой.

Я хотел бы получить две части информации: (1) список последовательных отрезков, которые опция имеет за временной ряд;и (2) даты, связанные с этими последовательными записями.

Например,

1900-01-01  Good
1900-01-02  Good
1900-01-03  Good
1900-01-04  Estimated
1900-01-05  Good
1900-01-06  Good
1900-01-07  Estimated
1900-01-08  Good

Так что здесь мы на благо, у нас будет последовательный список 3,2,1, и я быхотел бы вернуть список дат с 1900-01-01 по 1900-01-03, с 1900-01-05 по 1900-01-06 и 1900-01-08, связанный со списком 3,2,1.

Ответы [ 3 ]

1 голос
/ 16 мая 2019
library(data.table)
setDT(df)

out <- 
  df[order(Date), .(start = Date[1], end = Date[.N], .N), 
     by = .(Quality, id = rleid(Quality))][, -'id']

out[Quality == 'Good']
#    Quality      start        end N
# 1:    Good 1900-01-01 1900-01-03 3
# 2:    Good 1900-01-05 1900-01-06 2
# 3:    Good 1900-01-08 1900-01-08 1

Используемые данные

df <- fread('
Date  Quality
1900-01-01  Good
1900-01-02  Good
1900-01-03  Good
1900-01-04  Estimated
1900-01-05  Good
1900-01-06  Good
1900-01-07  Estimated
1900-01-08  Good
')

df[, Date := as.Date(Date)]
1 голос
/ 16 мая 2019

Одна dplyr возможность может быть:

df %>%
 mutate(rleid = with(rle(V2), rep(seq_along(lengths), lengths)),
        V1 = as.Date(V1, format = "%Y-%m-%d")) %>%
 group_by(rleid, V2) %>%
 summarise(res = paste0(min(V1), ":", max(V1)))

  rleid V2        res                  
  <int> <chr>     <chr>                
1     1 Good      1900-01-01:1900-01-03
2     2 Estimated 1900-01-04:1900-01-04
3     3 Good      1900-01-05:1900-01-06
4     4 Estimated 1900-01-07:1900-01-07
5     5 Good      1900-01-08:1900-01-08

Или:

df %>%
 mutate(rleid = with(rle(V2), rep(seq_along(lengths), lengths)),
        V1 = as.Date(V1, format = "%Y-%m-%d")) %>%
 group_by(rleid, V2) %>%
 summarise(res = paste0(min(V1), ":", max(V1))) %>%
 group_by(V2) %>%
 mutate(rleid = seq_along(rleid)) %>%
 arrange(V2, rleid)

  rleid V2        res                  
  <int> <chr>     <chr>                
1     1 Estimated 1900-01-04:1900-01-04
2     2 Estimated 1900-01-07:1900-01-07
3     1 Good      1900-01-01:1900-01-03
4     2 Good      1900-01-05:1900-01-06
5     3 Good      1900-01-08:1900-01-08

Или:

df %>%
 mutate(rleid = with(rle(V2), rep(seq_along(lengths), lengths)),
        V1 = as.Date(V1, format = "%Y-%m-%d")) %>%
 group_by(rleid, V2) %>%
 summarise(res = paste0(min(V1), ":", max(V1)),
           n = n()) %>%
 group_by(V2) %>%
 mutate(rleid = seq_along(rleid)) %>%
 arrange(V2, rleid)

  rleid V2        res                       n
  <int> <chr>     <chr>                 <int>
1     1 Estimated 1900-01-04:1900-01-04     1
2     2 Estimated 1900-01-07:1900-01-07     1
3     1 Good      1900-01-01:1900-01-03     3
4     2 Good      1900-01-05:1900-01-06     2
5     3 Good      1900-01-08:1900-01-08     1
1 голос
/ 16 мая 2019

Вы можете использовать rle

В следующих разделах показаны последовательные длины для Good

encodes <- rle(df$Quality)
encodes$lengths[encodes$values == "Good"]
[1] 3 2 1

Получение даты может быть сделано непосредственно из df

Данные:

df <- read.table(text = "Date Quality
1900-01-01  Good
1900-01-02  Good
                 1900-01-03  Good
                 1900-01-04  Estimated
                 1900-01-05  Good
                 1900-01-06  Good
                 1900-01-07  Estimated
                 1900-01-08  Good", header = T, stringsAsFactors = F)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...