【问题标题】:Calculating average for certain time period in every year计算每年特定时间段的平均值
【发布时间】:2019-06-22 02:46:45
【问题描述】:

我需要每年为我的数据计算季节性平均值,平均值的计算不在同一个日历年。我已经按日期定义了季节,并希望每年计算该时间段的平均温度、降水量等(例如,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) 

谢谢

【问题讨论】:

  • 你能给出想要的输出吗(对于你的一小部分数据)?数据中名为[, 1] 的列是否提供了降水?您是否需要使用 xts 包的方法,或者这正是您用来获取示例数据的方法?
  • 你没有让帮助你变得容易......你能在你的问题中包括一个示例输出(例如一个表)和示例数据(另一个表),显示你希望如何转换事情吗?您包含的数据看起来没有包含足够的降水/温度信息。还有,你为什么用xts?
  • 我想要的输出是每个季节/年变量的平均值。我在这里只使用 xts 来获取示例数据,我正在寻找任何包来计算平均值。据我探索,lubridate 和 xts 可用于按月或按周计算平均值,但我还没有找到一种方法来计算两个日历年中存在的选定日期的平均值。
  • 抱歉,我将编辑问题以使其清楚。

标签: r time-series average


【解决方案1】:

这是一种使用 tidyverse 语法的以数据框为中心的方法(如果您愿意,可以将其翻译为基础 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

【讨论】:

  • 感谢您的帮助。你能解释一下'-60'在group_by函数中的作用吗?它是否从前面步骤中定义的同一年减去 60 天?
  • 是的,它将所有日期向后移动 60 天,因此每次运行都在一年内。 format(..., '%Y') 提取那一年,然后可用于分组运行。
【解决方案2】:

如果我们将时间向前推 11 天,那么我们想要的日期是 2 月 26 日或之前的日期,所以让 tt 是这样一个日期向量,ok 是一个逻辑向量,如果对应的 @987654323 则为 TRUE @ 元素在 2 月 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)

【讨论】:

    猜你喜欢
    • 2020-03-02
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 2021-02-08
    • 2020-07-09
    相关资源
    最近更新 更多