【问题标题】:How to assign values to a new column based on a range of dates from that overlap years in R?如何根据 R 中重叠年份的日期范围为新列分配值?
【发布时间】:2022-10-16 10:12:48
【问题描述】:

我有一个增长率,从每年 4 次的个人测量中计算得出,我试图将其分配给一个名为 Year2 的不同时间框架(第 1 年的 8 月 1 日至第 2 年的 7 月 31 日,见附图)。

我的数据框:

ID Date Year Year2 Lag Lapse Growth Daily_growth
1 2009-07-30 2009 2009 NA NA 35.004 NA
1 2009-10-29 2009 2010 2009-07-30 91 days 31.585 0.347
1 2010-01-27 2010 2010 2009-10-29 90 days 63.769 0.709
1 2010-04-27 2010 2010 2010-01-27 90 days 28.329 0.315
1 2010-07-29 2010 2010 2010-04-27 93 days 32.068 0.345
1 2010-11-02 2010 2011 2010-07-29 96 days 128.1617320 1.335

我的增长率如下:

Growth_df <- Growth_df%>%
group_by(ID) %>% # Individuals we measured     
  mutate(Lag = lag(Date), #Last date measured   
         Lapse = round(difftime(Date, Lag, units = "days")), #days between Dates monitored  
         Daily_growth = as.numeric(Growth) / as.numeric(Lapse))

我要做的是分配每次测量之间的每日增长率,与 Year2 时间范围相匹配:

Growth_df <- Growth_df %>%
  mutate(Year = as.numeric(Year),
         Year2_growth = ifelse(Year == Year2, Daily_growth*Lapse, 0)) %>% 
  group_by(Year2) %>% 
  mutate(Year2_growth = sum(Year2_growth, na.rm = TRUE))

我的问题是我不知道如何获取年份之间的日期(代替 ifelse 语句中的 0 的东西)。我需要某种方法来计算从新的开始日期(8 月 1 日)到最近的测量还有多少天,然后将其乘以增长率,并提前结束(7 月 31 日)

我尝试按年和天制作第二个数据帧,然后在比较两个数据帧时分配增长率,但我一直被困在同一个问题上:划分时间帧。

【问题讨论】:

  • 您能否查看您的问题,看看是否有办法澄清您正在尝试做的事情?我还不明白这些句子指的是什么:“分配给称为 Year2 的不同时间范围”或“分配每次测量之间的每日增长率,与 Year2 时间范围相匹配”
  • 我猜你可能想要像Growth_df %&gt;% tidyr::complete(ID, Date = seq.Date(as.Date("2009-08-01"), as.Date("2011-11-01"), "year")) %&gt;% arrange(ID, Date) 这样的东西,它会为每个 ID 插入 8 月 1 日的行,你可以继续按照你的方式计算后续滞后?
  • 我正在努力自己想出解释! Year2 = 比如说 2008 年 8 月 31 日,到 2009 年 7 月 31 日,这将代表直到 2009 年这个时间范围内的所有增长,以这种方式重复直到现在)我需要这个时间范围作为南半球的冬季我在 8 月 1 日左右结束。 “分配每次测量之间的每日增长率,与 Year2 时间范围相匹配”:我需要找出每个 ID 在一年的 8 月 1 日(t)和次年的 7 月 31 日(t+1)之间增长了多少
  • 你能不能算出Daily_growth,然后按照上面的步骤加上8月1日,然后重新计算Lapse,那么每年的总增长就是group_by(Year) %&gt;% summarize(growth = sum(Lapse * Daily_growth))
  • 我不能,唉。尽管如此,我确实找到了一个糟糕的解决方案(见下文):

标签: r date dplyr overlap


【解决方案1】:

我确信有一种更有效的方法来处理这个问题,但这是我整理出来的方式:

  1. 制定我的时间表
  2. 为我想要的范围创建一个函数
  3. 为开始和结束范围创建一个数据框
  4. 将它们连接在一起
  5. 惊叹于我缺乏 r 技能。
    
    Start_dates <-  seq(ymd('2008-08-01'),ymd('2021-08-1'), by = '12 months')
    End_dates <- seq(ymd('2009-07-31'),ymd('2022-07-31'), by = '12 months')
    Year2_dates <- data.frame(Start_dates, End_dates)
    
    Year2_dates <- Year2_dates %>% 
      mutate(Year2 = format(as.Date(Start_dates, format="%d/%m/%Y"),"%Y"),
              Year2 = as.numeric(Year2) + 1) 
            
    Vegetation <- Vegetation %>% 
      left_join(Year2_dates)
             
             
    Range_finder <- function(x,y){
      
    as.numeric(difftime(x, y, unit = "days"))
    }
    
    Range_start <- Vegetation %>% 
      group_by(Year2, ID) %>% 
      filter(row_number()==1) %>% 
      filter(Year != Year2) #had to get rid of first year samples as they were the top row but didn't have a change in year
    
    
    Range_start <- Range_start %>% 
      mutate(Number_days_start = Range_finder(Date, Start_dates),
             Border_range = Number_days_start * Daily_veg) %>% 
      ungroup() %>% 
      select(ID, Year2, Date, Border_range) 
    
    
    Range_end <- Vegetation %>% 
      group_by(Year2, ID) %>% 
      filter(row_number()==n(),
             Year2 != 2022)
    
    Range_end <- Range_end %>% 
      mutate(Number_days_end = Range_finder(End_dates, Date),
             Border_range = Number_days_end * Daily_veg) %>% 
      ungroup() %>% 
      select(ID, Year2, Date, Border_range) 
    
    Ranges <- full_join(Range_start, Range_end)
    
    Vegetation <- Vegetation %>% 
      left_join(Ranges) 
    

【讨论】:

    猜你喜欢
    • 2016-01-10
    • 2021-06-07
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多