***注意:请不要链接类似的帖子。我发现了其他几处类似的帖子,但是他们的回答并没有解决我得到的错误:“ 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'必须是有限的数字
为什么?我该如何修复这段代码?
使用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)