Поиск и подсчет последовательных наблюдений, соответствующих условию - PullRequest
1 голос
/ 04 июня 2019

Я хочу подсчитать количество последовательных наблюдений, соответствующих условию. Например. Ниже foo я хотел бы подсчитать количество дней в марте, когда последовательные значения y меньше, чем одно стандартное отклонение от среднего значения y для этого месяца. Мои данные выложены как foo:

library(lubridate)
foo <- data.frame(x=seq.Date(as.Date("1981/1/1"), 
                             as.Date("2000/12/31"), "day"))
foo$y <- arima.sim(n = nrow(foo), list(ar = c(0.8)))

Я выяснил, как подсчитать количество дней в марте для каждого года, где y более чем на одно стандартное отклонение ниже среднего:

bar <- foo %>% filter(month(x) == 3 & y < mean(y)-sd(y)) %>% 
  group_by(year(x)) %>% tally()

Я бы хотел, чтобы это количество было только в том случае, если дни, соответствующие условию, являются последовательными. Например, если средняя температура для марта равна 0, а среднеквадратичное значение равно 1, а 5, 6 и 7 марта в 1990 году все ниже -1, то в 1990 году число будет равно 3. Если 21 марта также будет <-1 но 20 и 22 марта не <-1, число все равно будет равно 3, потому что 21 марта нет соседей, которые также <-1. </p>

Я представляю, rle входит в игру, но я не понимаю, как.

Любой совет приветствуется.

1 Ответ

1 голос
/ 06 июня 2019

Так что это должно работать.

foo %>%
  separate(x, sep = "-", into = c("year", "month", "day")) %>%
  filter(month == "03") %>%
  group_by(year) %>%
  mutate(z =  y < mean(y)-sd(y),
         g = {r <- rle(z)
              r$values[r$lengths < 2] <- FALSE
              inverse.rle(r)}) %>%
  tally(g)

# A tibble: 20 x 2
   year      n
   <chr> <int>
 1 1981      2
 2 1982      6
 3 1983      4
 4 1984      4
 5 1985      3
 6 1986      5
 7 1987      3
 8 1988      7
 9 1989      5
10 1990      4
11 1991      7
12 1992      4
13 1993      6
14 1994      5
15 1995      3
16 1996      5
17 1997      5
18 1998      4
19 1999      6
20 2000      6

Я оставил z и g, чтобы вы могли проверить результат.

ОБНОВЛЕНИЕ: rle берет последовательность и создает из нее объект с двумя элементами: 1. lengths - число, с которым элемент повторяется последовательно в последовательности. 2. values - соответствующее значение.

Возьмите этот пример:

seq <- c("a", "a", "a", "b", "b", "c")

rle_obj <- rle(seq)

rle_obj
Run Length Encoding
  lengths: int [1:3] 3 2 1
  values : chr [1:3] "a" "b" "c"

Теперь вы можете управлять последовательностью. Например, поверните «b» в последовательность 4 вместо 2:

rle_obj$lengths[rle_obj$values == "b"] <- 4

inverse.rle(rle_obj)
[1] "a" "a" "a" "b" "b" "b" "b" "c"

Надеюсь, это дало вам некоторое представление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...