在数据框中生成两个日期之间的日期

4
以下是输入和输出。我想将一个数据帧从输入格式转换为输出格式。
我现在写了一段代码,它可以完成任务。但我认为它非常低效。是否有更好的包或函数可以处理这个问题?
我的代码:
#create a output data frame to be apended later
output = data.frame(id1 = character(0), id2 = character(0), dates = character(0))

# for loop to get all possible combiation of dates

for (i in c(1:nrow(input))) {
  end  = as.Date('2016-07-18')
  len = as.numeric(end-input$min_date[i])
  output = rbind(output, as.data.frame(cbind(
    pid = rep(input$id1[i],len),
    cid = rep(input$id2[i],len),
    dates = as.character(seq(input$min_date[i], end, by='day'))
  )
  )
  )

翻译:

输入:

+------+--------+------------+------------+
| id1  |  id2   |  min_date  |  max_date  |
+------+--------+------------+------------+
| 3575 | 155443 | 2012-06-18 | 2016-07-18 |
| 3575 | 155450 | 2012-06-12 | 2016-07-18 |
+------+--------+------------+------------+

输出:

+------+--------+------------+
| id1  |  id2   |   dates    |
+------+--------+------------+
| 3575 | 155443 | 2012-06-18 |
| 3575 | 155443 | 2012-06-19 |
| 3575 | 155443 | 2012-06-20 |
| 3575 | 155443 | ..         |
| 3575 | 155443 | …          |
| 3575 | 155443 | 2016-07-18 |
|      |        |            |
| 3575 | 155450 | 2012-06-12 |
| 3575 | 155450 | 2012-06-13 |
| 3575 | 155450 | 2012-06-14 |
| 3575 | 155450 | …          |
| 3575 | 155450 | …          |
| 3575 | 155450 | 2016-07-18 |
+------+--------+------------+
2个回答

6
假设“min_date / max_date”列是“Date”类,我们使用“Map”获取每个“min_date”的序列,并在“list”中与相应的“max_date”对应,复制“df1”的行序列,行数为“list”元素的数量,通过扩展数据集基于“i1”创建一个“data.frame”,并根据“lst”元素连接“dates”。
lst <- Map(function(x, y) seq(x,y, by = "1 day"), df1$min_date, df1$max_date)
i1 <- rep(1:nrow(df1), lengths(lst)) 
data.frame(df1[i1,-3], dates = do.call("c", lst))

如果我们正在使用 dplyr


library(dplyr)
df1 %>%
   rowwise() %>% 
   do(data.frame(.[1:2], date = seq(.$min_date, .$max_date, by = "1 day")))

或者使用 data.table,我们可以在一行代码中完成此操作。

library(data.table) 
setDT(df1)[,.(date = seq(min_date, max_date, by = "1 day")) ,.(id1, id2)]

0
你可以使用 dplyrsplitstackshape 包。
library(dplyr)
library(splitstackshape)
df %>% 
   group_by(id1, id2) %>% 
   mutate(dates = paste(seq(as.Date(min_date),as.Date(max_date),by = 1), collapse = ',')) %>% 
   select(-c(min_date, max_date)) %>% 
   cSplit('dates', ',', 'long')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接