【问题标题】:How to combine data by two-year intervals in R如何在R中按两年间隔组合数据
【发布时间】:2021-11-15 16:09:41
【问题描述】:

我想在数据框中创建一个新列,按地区以两年为间隔对长度进行分类,但我不知道如何做。我在下面包含了 2010、2011、2012、2013、2014、2015 和 2019 年的示例数据。

我想:

  1. 找出每个地区的第一年。
  2. 将年份设置为每个地区两年间隔的起点。
  3. 如果该地区在该时间间隔内有两年的可用数据,请在新列中将两年时间间隔标记为“year1 - year2”。
  4. 如果不是,请在新列中保留年份。

我认为步骤 1 可以使用 min,步骤 3-4 可以使用 if_else,但我不确定如何执行步骤 2。

谢谢!

df <- data.frame(matrix(nrow=500, ncol=0))

set.seed(1)

df$region <- sample(c("North", "Central", "South"),
                       size = nrow(df), 
                       replace = TRUE)

df$year <- sample(c("2010", "2011", "2012", "2013", "2014", "2015", "2019"),
                    size = nrow(df), 
                    replace = TRUE)

df$length <- sample(1:100, size = nrow(df), replace=TRUE)

【问题讨论】:

    标签: r


    【解决方案1】:

    首先,将年份设为数字。

    获取每个地区的最短年份(恰好是所有地区的 2010 年)

    按年份获取每个区域的总长度(认为这是您想要做的,但必要时避免总和)。

    加入开始年份数据框(适用于所有开始 =/= 2010 年的情况)

    再次按地区分组,使用lead()检查每一年的下一个值是多少,以及这个值是否是当前年份之后的年份,从而创建一个区间。

    如果下一行是下一年,则将今年的长度添加到下一年,如果不是,则保持当前年份的长度为值。

    将间隔粘贴在一起

    
    df <- df %>% mutate(year = as.numeric(year))%>%
      tibble()
    
    start_year <- df %>%
      group_by(region)%>%
      summarise(start = min(year))
    
    data <-  df %>%
      arrange(year)%>%
      group_by(region, year)%>%
      summarise(length = sum(length), .groups = "drop")%>%
      left_join(start_year, by = "region") %>%
      group_by(region)%>%
      mutate(next_year = lead(year, 1))%>%
      ungroup()%>%
      mutate(successive_years = lead(year, 1)- year == 1,
             two_year_total = case_when(successive_years ~ length + lead(length, 1),
                                        !successive_years ~ length),
             interval = case_when(successive_years ~ paste0(year, "-", lead(year,1)),
                                  !successive_years ~ paste(year)),
             interval_length = case_when(successive_years == TRUE ~ two_year_total,
                                         !successive_years  ~ length)) %>%
      select(region, interval, interval_length)
    
    
    

    认为这大概就是您所需要的吗?当然可以提高效率。

    【讨论】:

    • 感谢您抽出宝贵时间帮助我!在这里,我不想总结长度。相反,当我想对长度进行与分布相关的分析(即 Kolmogorov-Smirnov)时,我希望能够按两年间隔对长度进行聚类(或分组)。您将如何修改代码以按间隔而不是总和对它们进行聚类?而且,您的示例代码会创建重叠的间隔(即 2010-2011 和 2011-2012)。我希望它们不要重叠(即 2010-2011 和 2012-2013)。
    【解决方案2】:

    好的,回复:您的评论。这有点棘手,但应用了类似的方法(也许最好返回并使用 purrr:: 整个过程,但沉没成本等等)。 真正的关键步骤是将长度存储为列表,从开始的两年期间存储为列表,然后与之前类似的锤子,同时在 mutate(interval =...) 步骤中交替滞后和领先有点棘手。

    考虑到游戏的变化,我希望有一个很多更好的解决方案。期待有人发布一个:)

    df <- df %>% mutate(year = as.numeric(year))%>%
      tibble()
    
    start_year <- df %>%
      group_by(region)%>%
      summarise(start = min(year), two_years = list(seq(start, 2030, 2)))
    
    df <- df %>% 
      arrange(region, year)%>%
      group_by(region, year)%>%
      summarise(length = list(length))%>%
      left_join(start_year, by = "region")%>%
      mutate(successive_years = lead(year, 1) - year == 1,
             start_interval = year %in% two_years[[1]])%>%
      ungroup()%>%
      mutate(interval = case_when(start_interval & successive_years ~ paste0(year, "-", lead(year, 1)),
                                  !start_interval & lag(successive_years, 1) ~ paste0(lag(year,1), "-", year),
                                  start_interval & !successive_years ~ paste(year),
                                  is.na(successive_years) ~ paste(year)))
    
    #unnest the list & get rid of unnecessary columns:
    df %>%
      group_by(region, interval)%>%
      summarise(length = unlist(length). groups = "drop")%>%
      select(-start, -two_years, -successive_years, -start_interval)
    

    【讨论】:

    • 就是这样!谢谢你!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2019-07-26
    • 2019-07-25
    • 2019-03-29
    相关资源
    最近更新 更多