【问题标题】:R Expand time series data based on start and end pointR根据起点和终点展开时间序列数据
【发布时间】:2020-11-24 19:40:59
【问题描述】:

我想我有一个非常简单的要求。我有以下数据框,其中“地点”是唯一标识符,而 start_date 和 end_date 可能重叠。每个 ID“地点”的值都是唯一的。

place  start_date   end_date value
1     2007-09-01  2010-10-12  0.5
2     2013-09-27  2015-10-11  0.7
...

我需要创建一个基于年份的变量,在其中我将时间序列按每年(从 1 月 1 日开始(即 2011-01-01)开始为那个特定的“地方”和“价值”。我的意思是这样的:

place  year  value 
1     2007    0.5   
1     2008    0.5   
1     2009    0.5   
1     2010    0.5   
2     2013    0.7    
2     2014    0.7    
2     2015    0.7    
...

对于两个不同的案例,有些案例存在重叠(即“地点”=1 和“年份”=2007),其中一个观察从一年开始,另一个观察从那一年继续。在这种情况下,我更喜欢在该特定年份结束的“价值”。因此,如果 place=1 的一个观察结果在 3 月以 2007 年结束,而另一个 place=1 从 4 月的 2007 年开始,那么如果有意义的话,place=1 的 year=2007 值将被标记为之前的“结束”值。

我只做到了这一点: 库(数据表) 数据 :=(start_date = as.Date(start_date), end_date = as.Date(end_date))] data[,num_mons:= length(seq(from=start_date, to=end_date, by='year')),by=1:nrow(data)]

我想写一个循环最有意义?

感谢您的帮助和建议。

【问题讨论】:

    标签: r loops time-series data-manipulation


    【解决方案1】:

    使用 tidyverse 解决方案可能如下所示:

    library(dplyr)
    library(stringr)
    library(purrr)
    library(tidyr)
    
    data <- tibble(place = c(1, 2),
                   start_date = c('2007-09-01',
                                  '2013-09-27'),
                   end_date = c('2010-10-12',
                                '2015-10-11'),
                   value = c(0.5, 0.7))
    
    data %>%
      mutate(year = map2(start_date,
                         end_date,
                         ~ as.character(str_extract(.x, '\\d{4}'): 
                                        str_extract(.y, '\\d{4}')))) %>%
      separate_rows(year) %>%
      filter(!year %in% c('c', '')) %>%
      select(place, year, value)
    
    #   place year  value
    #   <dbl> <chr> <dbl>
    # 1     1 2007    0.5
    # 2     1 2008    0.5
    # 3     1 2009    0.5
    # 4     1 2010    0.5
    # 5     2 2013    0.7
    # 6     2 2014    0.7
    # 7     2 2015    0.7
    

    我无法理解您问题的第三段(“有……”)。在我看来,这是一个单独的问题。如果是这种情况,请考虑将问题移至 SO 上的单独帖子。如果不是单独的问题,请重新编写段落。

    【讨论】:

    • 谢谢,在这种情况下,我会在另一个问题中问第二个问题。这比我一开始解释的要复杂一些。
    【解决方案2】:

    您可以执行以下操作:

    library(lubridate)
    library(tidyverse)
    df %>%
      group_by(place) %>%
      mutate(year = list(seq(year(ymd(start_date)), year(ymd(end_date)))))%>%
      unnest(year)%>%
      select(place,year,value)
    
    # A tibble: 7 x 3
    # Groups:   place [2]
      place  year value
      <int> <int> <dbl>
    1     1  2007   0.5
    2     1  2008   0.5
    3     1  2009   0.5
    4     1  2010   0.5
    5     2  2013   0.7
    6     2  2014   0.7
    7     2  2015   0.7
    

    【讨论】:

      猜你喜欢
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-27
      • 2017-10-02
      • 1970-01-01
      相关资源
      最近更新 更多