【问题标题】:Create day index based on water year根据水年创建日索引
【发布时间】:2018-06-15 19:45:58
【问题描述】:

我正在处理水文数据,我需要水年。我已经根据之前在此论坛上发布的功能成功创建了一个水年专栏。我想要一个伴随的water day 范围从1-365(闰年为366)以匹配水年序列。请注意,水年由其结束的日历年指定。例如,2010 年水年从 2009 年 10 月 1 日开始,到 2010 年 9 月 30 日结束。

基本上我想要一个从 1-365(闰年为 366)开始的列,只要日期是每年 10 月 1 日。

我的数据集范围从 1950 年到 2099 年,所以我需要某种方式来自动化这个过程。这个问题的闰年部分给我带来了麻烦。

我在下面提供了代码来创建数据集。

# Create a data_set with datetime, year, month, day, jd, wtr_yr

library(lubridate)

datetime <- seq(as.Date("1950/1/1"), as.Date("2099/12/31"), by = "day")
year <- year(datetime)
month <- month(datetime)
day <- day(datetime)
julian_day <- yday(datetime)

# make dataframe with all time components
datetime_dataframe <- data.frame(datetime, year, month, day, julian_day)

# Create function to derive water year. Credit goes to Caner and MrFlick.

wtr_yr <- function(dates, start_month=10) {
  # Convert dates into POSIXlt
  dates.posix = as.POSIXlt(dates)
  # Year offset
  offset = ifelse(dates.posix$mon >= start_month - 1, 1, 0)
  # Water year
  adj.year = dates.posix$year + 1900 + offset
  # Return the water year
  adj.year
}

#  Use fn to add water year to the dataframe
datetime_dataframe$wtr_yr <-wtr_yr(datetime_dataframe$datetime)

head(datetime_dataframe)

【问题讨论】:

    标签: r date time


    【解决方案1】:

    这是一种可行的方法。我从 1949-10-01 创建了日期序列。我先添加了water.year。无论月份 == 9 和日期 == 30 的行都被标记并标记为 1。其余的变为 0。使用此列,我为水年创建了一个分组变量。 cumsum(c(F, diff(water.year) &lt; 0)) 正在做这项工作。一旦我有了分组变量,我就创建了日期序列。我在下面留下了最终结果的一部分。

    library(dplyr)
    library(lubridate)
    
    mydata <- data.frame(date = seq(as.Date("1949-10-01"),as.Date("2099-12-31"), by = "day")) %>%
              mutate(year = year(date),
                     month = month(date),
                     day = day(date),
                     julian_day = yday(date),
                     water.year = if_else(month == 9 & day == 30, 1, 0))
    
    mydata %>%
    group_by(water.year = cumsum(c(F, diff(water.year) < 0))) %>%
    mutate(water.day = 1:n())
    
             date year month day julian_day water.year water.day
    1  1952-09-01 1952     9   1        245          2       337
    2  1952-09-02 1952     9   2        246          2       338
    3  1952-09-03 1952     9   3        247          2       339
    28 1952-09-28 1952     9  28        272          2       364
    29 1952-09-29 1952     9  29        273          2       365
    30 1952-09-30 1952     9  30        274          2       366
    

    【讨论】:

    • 首先,谢谢!此代码中唯一缺少的是水年列(从 1951 年到 2100 年)。如果您将我在原始问题中发布的 wtr_yr 函数添加到您的代码中,您就可以到达那里。即 wtr_yr = start_month - 1, 1, 0 ) # 水年 adj.year = dates.posix$year + 1900 + offset # 返回水年 adj.year } mydata$wtr_yr
    【解决方案2】:

    这应该可行。我刚刚使用了difftime,并指出您希望 wtr_day 是上一个 wtr_yr 中从 9 到 30 的天数。

    library(tidyverse)
    new_df <- datetime_dataframe %>%
      group_by(wtr_yr) %>% 
      mutate(wtr_day = (as.integer(difftime(datetime,ymd(paste0(wtr_yr - 1 ,'-09-30')), units = "days"))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      相关资源
      最近更新 更多