Расчет среднего за определенный период времени в каждом году - PullRequest
0 голосов
/ 29 января 2019

Мне нужно рассчитывать сезонные средние для моих данных каждый год, расчет среднего значения не в том же календарном году.Я определил сезон по дате и собираюсь рассчитать среднюю температуру, количество осадков и т. Д. Для этого периода времени каждый год (например, 12/21/1981 до 02/15/1982, 12/21/1982 до 02/15/1983) и т. Д.

Есть ли эффективный способ сделать это в R?

Ниже приведены мои данные:

library(xts)
seq <- timeBasedSeq('1981-01-01/1985-06-30') 
Data <- xts(1:length(seq),seq) 

Спасибо

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Если мы перенесем время на 11 дней, то мы хотим, чтобы даты были такими же, как 26 февраля или ранее, поэтому пусть tt будет таким вектором даты, а ok будет логическим вектором, который ИСТИНА, если соответствующий tt Элемент не позднее 26 февраля.В завершение агрегируйте Data[ok] по состоянию на конец периода года.

tt <- time(Data) + 11
ok <- format(tt, "%m-%d") < "02-26"
aggregate(Data[ok], as.integer(as.yearmon(tt))[ok], mean)

, что дает:

1981   23.0
1982  382.5
1983  747.5
1984 1112.5
1985 1478.5

Если вы хотите сделать это без xts, тогда предположите, что наш ввод DF, попробуйте это:

DF <- fortify.zoo(Data) # input

tt <- DF[, 1] + 11
ok <- format(tt, "%m-%d") < "02-26"
year <- as.numeric(format(tt, "%Y"))
aggregate(DF[ok, -1, drop = FALSE], list(year = year[ok]), mean)
0 голосов
/ 29 января 2019

Вот подход, ориентированный на фреймы данных, использующий грамматику приливов (которая может быть переведена в базу R, если вы предпочитаете):

library(tidyverse)

df_in <- tibble(
    date = seq(as.Date('1981-01-01'), as.Date('1985-06-30'), by = 'day'), 
    x = seq_along(date)
)

str(df_in)
#> Classes 'tbl_df', 'tbl' and 'data.frame':    1642 obs. of  2 variables:
#>  $ date: Date, format: "1981-01-01" "1981-01-02" ...
#>  $ x   : int  1 2 3 4 5 6 7 8 9 10 ...

df_out <- df_in %>% 
    # reformat data to keep months and days, but use identical year, so...
    mutate(same_year = as.Date(format(date, '1970-%m-%d'))) %>% 
    # ...we can subset to rows we care about with simpler logic
    filter(same_year < as.Date('1970-02-15') | same_year > as.Date('1970-12-21')) %>% 
    # shift so all in one year and use for grouping
    group_by(run = as.integer(format(date - 60, '%Y'))) %>% 
    summarise(    # aggregate each gruop
        start_date = min(date), 
        end_date = max(date), 
        mean_x = mean(x)
    )

df_out
#> # A tibble: 5 x 4
#>     run start_date end_date   mean_x
#>   <int> <date>     <date>      <dbl>
#> 1  1980 1981-01-01 1981-02-14     23
#> 2  1981 1981-12-22 1982-02-14    383
#> 3  1982 1982-12-22 1983-02-14    748
#> 4  1983 1983-12-22 1984-02-14   1113
#> 5  1984 1984-12-22 1985-02-14   1479
...