【问题标题】:Fill dates and create new rows in dataframe填写日期并在数据框中创建新行
【发布时间】:2017-06-19 14:54:23
【问题描述】:
    rptdate       st
1   2/18/2017   2/12/2017
2   2/25/2017   2/19/2017
3   3/4/2017    2/26/2017
4   3/11/2017   3/5/2017
5   3/18/2017   3/12/2017
6   3/25/2017   3/19/2017
7   4/1/2017    3/26/2017
8   4/8/2017    4/2/2017
9   4/15/2017   4/9/2017
10  4/22/2017   4/16/2017
11  4/29/2017   4/23/2017
12  5/6/2017    4/30/2017
13  5/13/2017   5/7/2017
14  5/20/2017   5/14/2017
15  5/27/2017   5/21/2017
16  6/3/2017    5/28/2017
17  6/10/2017   6/4/2017

所以基本上 rptdate 是一堆星期六,而 st 是每个星期天。

我想以这种方式重塑这个数据框(数据是日期格式):

我想做的是:

i=1
j=1
While (rptdate[i][j]>=st[i][j])
  {add a new row where rptdate[i][j+1]= rptdate[i][j] and st[i][j+1]=rptdate[i][j]+1}

所以基本上,我想要的新数据框应该是这样的:

     rptdate       st
1   2/18/2017   2/12/2017
    2/18/2017   2/13/2017
    2/18/2017   2/14/2017
    2/18/2017   2/15/2017
    2/18/2017   2/16/2017
    2/18/2017   2/17/2017
    2/18/2017   2/18/2017
2   2/25/2017   2/19/2017
    2/25/2017   2/20/2017
    2/25/2017   2/21/2017
    2/25/2017   2/22/2017
    2/25/2017   2/23/2017
    2/25/2017   2/24/2017
    2/25/2017   2/25/2017

非常感谢您的宝贵时间。

【问题讨论】:

  • 你能用文字解释你想要做什么吗?

标签: r date dataframe


【解决方案1】:

这是基于 R 的一个想法。您需要先将变量转换为日期。然后为每个日期用额外的 7 行(1 周)扩展数据框。使用seq 生成所有缺失的日期并将它们添加到您的st 变量中。

d2[] <- lapply(d2, function(i) as.Date(i, format = '%m/%d/%Y'))
d3 <- d2[rep(row.names(d2), each = 7),]
d3$st<- do.call(c, Map(function(x, y)seq(x, y, by = 1), d2$st, d2$rptdate))

head(d3, 10)
#       rptdate         st
#1   2017-02-18 2017-02-12
#1.1 2017-02-18 2017-02-13
#1.2 2017-02-18 2017-02-14
#1.3 2017-02-18 2017-02-15
#1.4 2017-02-18 2017-02-16
#1.5 2017-02-18 2017-02-17
#1.6 2017-02-18 2017-02-18
#2   2017-02-25 2017-02-19
#2.1 2017-02-25 2017-02-20
#2.2 2017-02-25 2017-02-21
...

【讨论】:

  • 非常感谢您的帮助。
【解决方案2】:

library(data.table)

dt <- data.table(V1=as.Date(c("2/18/2017","2/25/2017","3/4/2017","3/11/2017"),format = "%m/%d/%Y"),
                 V2=as.Date(c("2/12/2017","2/19/2017","2/26/2017","3/5/2017"),format = "%m/%d/%Y"))
for(i in 0:6){
  dt[,paste0("colomn_i",i):=V1-i]
}
dt[,V2:=NULL]
temp <- melt(dt,id.vars = "V1")
setorder(temp,V1,value)
temp[,variable:=NULL]

尽管最终V2 是不需要的

【讨论】:

    【解决方案3】:

    这是一个使用来自dplyrlubridate 的函数的示例。 dt2 将是最终输出。

    # Create example data frame
    dt <- read.table(text = "rptdate st
    2/18/2017   2/12/2017
    2/25/2017   2/19/2017
    3/4/2017    2/26/2017
    3/11/2017   3/5/2017
    3/18/2017   3/12/2017
    3/25/2017   3/19/2017
    4/1/2017    3/26/2017
    4/8/2017    4/2/2017
    4/15/2017   4/9/2017
    4/22/2017   4/16/2017
    4/29/2017   4/23/2017
    5/6/2017    4/30/2017
    5/13/2017   5/7/2017
    5/20/2017   5/14/2017
    5/27/2017   5/21/2017
    6/3/2017    5/28/2017
    6/10/2017   6/4/2017",
                     header = TRUE, stringsAsFactors = FALSE)
    
    # Load packages
    library(dplyr)
    library(lubridate)
    
    # Process the data
    dt2 <- dt %>%
      mutate(rptdate = mdy(rptdate), st = mdy(st)) %>%
      rowwise() %>%
      do(data_frame(rptdate = rep(.$rptdate[1], 7),
                    st = seq(.$st[1], .$rptdate[1], by = 1))) %>%
      mutate(rptdate = format(rptdate, "%m/%d/%Y"),
             st = format(st, "%m/%d/%Y"))
    

    或者您可以使用tidyverse 中的map2unnest 函数。

    # Load packages
    library(tidyverse)
    library(lubridate)
    
    # Process the data
    dt2 <- dt %>%
      mutate(rptdate = mdy(rptdate), st = mdy(st)) %>%
      mutate(st = map2(st, rptdate, seq, by = 1)) %>%
      unnest() %>%
      mutate(rptdate = format(rptdate, "%m/%d/%Y"),
             st = format(st, "%m/%d/%Y"))
    

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多