修正与在R中的开始日期和结束日期之间创建日期序列有关的错误

问题描述 投票:1回答:1

***注意:请不要链接类似的帖子。我发现了其他几处类似的帖子,但是他们的回答并没有解决我得到的错误:“ seq.int(0,to0-from,by)中的错误:'to'必须为有限数”或“ from必须为长度为1“...。我希望了解为什么会出现这些错误语句,以及如何防止它们出现...谢谢!

我有如下数据框

    id  startdate  enddate
    1   01/01/2011 01/05/2011
    1   02/03/2012 02/05/2012
    2   03/04/2013 03/06/2013
    3   04/06/2014 04/09/2014

我想变换数据框以便创建以下内容:

    id   date
    1    01/01/2011
    1    01/02/2011
    1    01/03/2011
    1    01/04/2011
    1    01/05/2011
    1    02/03/2012
    1    02/04/2012
    1    02/05/2012
    2    03/04/2013
    2    03/05/2013
    2    03/06/2013 

....依此类推,以填充开始日期和结束日期之间的日期顺序

我已经尝试了以下方法。...

one<-as.data.table(one)
one[, startdate:=as.character(startdate)]
one[, enddate:=as.character(enddate)]
one[, startdate:=as.Date(startdate, format="%m/%d/%Y")]
one[, enddate:=as.Date(enddate, format="%m/%d/%Y")]
one<-as.data.frame(one)
one%>%
  rowwise() %>%
  do(data.frame(id=.$id, date=seq(.$startdate,.$enddate,by="day")))

[运行此命令时,出现以下错误:seq.int(0,to0-from,by)中的错误:'to'必须是有限的数字

为什么?我该如何修复这段代码?

r dataframe data.table
1个回答
1
投票

使用data.table,我们可以使用Map。将'startdate''enddate'转换为Date类,使用Map获得相应元素的seq uance,rep根据lengths输出的list来确定'id'日期,并置日期的list以创建两列输出

library(data.table)
one[, {lst1 <- Map(seq, as.IDate(startdate, "%m/%d/%Y"),
                       as.IDate(enddate, "%m/%d/%Y"),
                      MoreArgs = list(by = "day"))
         .(id = rep(id, lengths(lst1)), date = do.call(c, lst1))}]
#    id       date
# 1:  1 2011-01-01
# 2:  1 2011-01-02
# 3:  1 2011-01-03
# 4:  1 2011-01-04
# 5:  1 2011-01-05
# 6:  1 2012-02-03
# 7:  1 2012-02-04
# 8:  1 2012-02-05
# 9:  2 2013-03-04
#10:  2 2013-03-05
#11:  2 2013-03-06
#12:  3 2014-04-06
#13:  3 2014-04-07
#14:  3 2014-04-08
#15:  3 2014-04-09

如果“日期”列中有多种格式,则从anydate中选择anytime来自动将某些格式转换为Date

library(anytime)
one[, {lst1 <- Map(seq, anydate(startdate),
                    anydate(enddate),
                   MoreArgs = list(by = "day"))
      .(id = rep(id, lengths(lst1)), date = do.call(c, lst1))}]

或使用tidyverse

library(dplyr)
library(purrr)
library(tidyr)
library(lubridate)
one %>% 
   transmute(id, date = map2(mdy(startdate), mdy(enddate), seq, by = 'day')) %>% 
   unnest(c(date))
# A tibble: 15 x 2
#     id date      
#   <int> <date>    
# 1     1 2011-01-01
# 2     1 2011-01-02
# 3     1 2011-01-03
# 4     1 2011-01-04
# 5     1 2011-01-05
# 6     1 2012-02-03
# 7     1 2012-02-04
# 8     1 2012-02-05
# 9     2 2013-03-04
#10     2 2013-03-05
#11     2 2013-03-06
#12     3 2014-04-06
#13     3 2014-04-07
#14     3 2014-04-08
#15     3 2014-04-09

数据

one <- structure(list(id = c(1L, 1L, 2L, 3L), startdate = c("01/01/2011", 
"02/03/2012", "03/04/2013", "04/06/2014"), enddate = c("01/05/2011", 
"02/05/2012", "03/06/2013", "04/09/2014")), class = "data.frame", row.names = c(NA, 
-4L))

setDT(one)
© www.soinside.com 2019 - 2024. All rights reserved.