【问题标题】:Expanding a dataframe from years to months将数据框从几年扩展到几个月
【发布时间】:2019-12-11 16:19:05
【问题描述】:

多年来,我的数据框有一列。见下文:

D <- as.data.frame(cbind(c(1998,1998,1999,1999,2000,2001,2001), c(1,2,2,5,1,3,4), c(1,5,9,2,NA,7,8)))
colnames(D) <- c('year','var1','var2')
D$start <- D$year*100+1
D$end <- D$year*100+12
print(D)
  year var1 var2  start    end
1 1998    1    1 199801 199812
2 1998    2    5 199801 199812
3 1999    2    9 199901 199912
4 1999    5    2 199901 199912
5 2000    1   NA 200001 200012
6 2001    3    7 200101 200112
7 2001    4    8 200101 200112

我想将每一行复制 12 次,每个月在开始列和结束列之间复制一次。在此示例中,我创建了 1 月和 12 月的开始列和结束列,但理论上它们可能会有所不同。显然我正在处理一个非常大的数据集,所以我想知道如何用一两行来完成它(最好使用 dplyr,因为这是我最习惯的编码语言)。

【问题讨论】:

  • 不是很重要,但是 dplyr 不是一种语言,它只是一个非常流行的 R 包。也就是说,一旦您将开始和结束日期转换为实际日期对象,它可能会被 this post 和其他一些人所欺骗
  • 你能展示一个预期输出的例子吗?

标签: r dplyr


【解决方案1】:

如果您想要每一行的所有月份,我会这样做:

months = expand.grid(year = unique(d$year), month = 1:12)
left_join(D, months, by = "year")

如果您希望 most 个月持续 most 年,您可以filter 在下一步中剔除您不想要的那些。

如果您真的想使用您创建的startend 列,我会这样做:

D %>% mutate(month = Map(seq, start, end)) %>%
  tidyr::unnest(cols = month)

【讨论】:

    【解决方案2】:

    我们可以从tidyrexpand

    expand(D, year = unique(year), month = 1:12)  %>%
        left_join(D, by = 'year')
    

    【讨论】:

      【解决方案3】:

      这也有效:

      D %>% 
        rowid_to_column() %>%
        gather(key = key, value = date, start, end) %>% 
        select(-key) %>% 
        group_by(rowid) %>% 
        complete(date = full_seq(date, 1)) %>% 
        fill(everything(), -rowid, .direction = "downup") %>% 
        ungroup() %>% 
        arrange(rowid)
      

      如果要保留开始和结束列,请在 ungroup() 之前添加以下内容:

       mutate(start = min(date), end = max(date))
      

      【讨论】:

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