【问题标题】:How to combine winter months of two consecutive years如何结合连续两年的冬季月份
【发布时间】:2018-10-03 06:33:18
【问题描述】:

我有一个跨越几年的几个物种的计数数据。我只想查看每年冬季每个物种的丰度动态。问题是冬季跨越两年,即十一月、十二月和明年一月。现在,我想结合连续两年的冬季每个物种的丰度,做一些分析。例如,我想在第一轮中对 2005 年 11 月至 12 月和 2006 年 1 月进行子集分析,然后在第二轮中对 2006 年 11 月至 12 月和 2007 年 1 月进行子集,然后重复相同的分析等等.... 我怎样才能在 R 中做到这一点?

这是数据示例

date    species year    month   day abundance   temp
9/3/2005    A   2005    9   3   3   19
9/15/2005   B   2005    9   15  30  16
10/4/2005   A   2005    10  4   24  12
11/6/2005   A   2005    11  6   32  14
12/8/2005   A   2005    12  8   15  13
1/3/2005    A   2006    1   3   64  19
1/4/2006    B   2006    1   4   2   13
2/10/2006   A   2006    2   10  56  12
2/8/2006    A   2006    1   3   34  19
3/9/2006    A   2006    1   3   64  19

【问题讨论】:

  • 解决这个问题的简单方法是为月份添加一列,并根据一年中的月份对数据进行子集化。如果您可以使用 dput 为我们提供可重现的示例,那是冬季月份。我可以帮你更多

标签: r time-series


【解决方案1】:

我将您的日期列转换为日期类(可能使用lubridate)并删除年月日列,因为它们是多余的。

然后用季节性年份(定义为年份,除非月份是一月,那么它是上一年)创建一个新列。另一列由定义行的季节的case_when 组成。

library(dplyr)
library(lubridate)

# converts to date format
df$date <- mdy(df$date)

# add in columns
df <- mutate(df,
       season_year = ifelse(month(date) == 1, year(date) - 1, year(date)),
       season = case_when(
        month(date) %in% c(2, 3, 4) ~ "Spring",
        month(date) %in% c(5, 6, 7) ~ "Summer",
        month(date) %in% c(8, 9, 10) ~ "Autumn",
        month(date) %in% c(11, 12, 1) ~ "Winter",
        T ~ NA_character_
       ))

#          date species abundance temp season_year season
# 1  2005-09-03       A         3   19        2005 Autumn
# 2  2005-09-15       B        30   16        2005 Autumn
# 3  2005-10-04       A        24   12        2005 Autumn
# 4  2005-11-06       A        32   14        2005 Winter
# 5  2005-12-08       A        15   13        2005 Winter
# 6  2005-01-03       A        64   19        2004 Winter
# 7  2006-01-04       B         2   13        2005 Winter
# 8  2006-02-10       A        56   12        2006 Spring
# 9  2006-02-08       A        34   19        2006 Spring
# 10 2006-03-09       A        64   19        2006 Spring

然后您可以group_by() 和/或filter() 您的数据进行进一步分析:

df %>%
  group_by(season_year) %>%
  filter(season == "Winter") %>%
  summarise(count = sum(abundance))

# # A tibble: 2 x 2
#   season_year count
#         <dbl> <int>
# 1        2004    64
# 2        2005    49

【讨论】:

    【解决方案2】:

    data.table 解决方案:

    首先创建一个包含起始日期和季节年份的查找表,然后使用 foverlaps 执行重叠连接

    library( data.table )
    

    样本数据

    dt <- fread("date    species year    month   day abundance   temp
    9/3/2005    A   2005    9   3   3   19
    9/15/2005   B   2005    9   15  30  16
    10/4/2005   A   2005    10  4   24  12
    11/6/2005   A   2005    11  6   32  14
    12/8/2005   A   2005    12  8   15  13
    1/3/2005    A   2006    1   3   64  19
    1/4/2006    B   2006    1   4   2   13
    2/10/2006   A   2006    2   10  56  12
    2/8/2006    A   2006    1   3   34  19
    3/9/2006    A   2006    1   3   64  19", header = TRUE)
    

    创建查找表

    在这里,您可以定义季节的名称、开始和结束。根据自己的需要进行调整。由于您想单独分析季节,我建议保留唯一的季节名称(此处:基于季节的开始年份)。

    dt.season <- data.table( from = seq( as.Date("1999-02-01"), length.out = 100, by = "3 month"),
                             to = seq( as.Date("1999-05-01"), length.out = 100, by = "3 month") - 1 )
    dt.season[, season := paste0( c( "spring", "summer", "autumn", "winter" ), "-", year( from ) )]
    setkey( dt.season, from, to )
    
    head(dt.season,6)
    
    #          from         to      season
    # 1: 1999-02-01 1999-04-30 spring-1999
    # 2: 1999-05-01 1999-07-31 summer-1999
    # 3: 1999-08-01 1999-10-31 autumn-1999
    # 4: 1999-11-01 2000-01-31 winter-1999
    # 5: 2000-02-01 2000-04-30 spring-2000
    # 6: 2000-05-01 2000-07-31 summer-2000
    

    并执行加入

    #set dt$date as dates
    dt[, date := as.Date(date, format = "%m/%d/%Y")]
    
    #create dummy variables to join on
    dt[, `:=`( from = date, to = date)]
    
    #create an overlap join, and clean the dummies used for the join
    foverlaps( dt, dt.season)[, `:=`(from = NULL, to = NULL, i.from = NULL, i.to = NULL)][]
    
    #         season       date species year month day abundance temp
    #  1: autumn-2005 2005-09-03       A 2005     9   3         3   19
    #  2: autumn-2005 2005-09-15       B 2005     9  15        30   16
    #  3: autumn-2005 2005-10-04       A 2005    10   4        24   12
    #  4: winter-2005 2005-11-06       A 2005    11   6        32   14
    #  5: winter-2005 2005-12-08       A 2005    12   8        15   13
    #  6: winter-2004 2005-01-03       A 2006     1   3        64   19
    #  7: winter-2005 2006-01-04       B 2006     1   4         2   13
    #  8: spring-2006 2006-02-10       A 2006     2  10        56   12
    #  9: spring-2006 2006-02-08       A 2006     1   3        34   19
    # 10: spring-2006 2006-03-09       A 2006     1   3        64   19
    

    您现在可以通过season 轻松分组/求和/分析

    【讨论】:

      【解决方案3】:

      我认为最简单的方法是考虑 2006 年冬季包括 2006 年 11 月、2006 年 12 月和 2007 年 1 月,您可以添加一个列 winterid &lt;- ifelse(data$month %in% c(11,12), data$year, ifelse(data$month == 1, data$year-1, "notwinter"))。 您现在可以对连续的冬季进行子集化。根据您的符号进行调整。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-27
        • 1970-01-01
        • 1970-01-01
        • 2016-11-07
        • 2020-12-29
        • 1970-01-01
        • 2020-10-28
        相关资源
        最近更新 更多