我有一个data.frame如下。它在每列中有许多行和多个值
ID=c(466,469,471,480,509,513,515,517,518,519,520,521,453,455,463,474,477,479,481,482,484,489,496,497,500,503)
name=c(rep("a",12),rep("b",14))
start=c(rep("2/13/2013",12),rep("3/6/2013",14))
end=c(rep("2/20/2013",12),rep("3/13/2013",14))
start=as.Date(start,"%m/%d/%Y")
end=as.Date(end,"%m/%d/%Y")
maint=data.frame(ID,name,start,end)
> (maint[1,])
ID name start end
1 466 a 2013-02-13 2013-02-20
我想获取数据并将其转换如下。我正在为原始数据的第一行提供示例,但我希望对原始数据的所有行执行相同的操作。请告知如何做到这一点。
我正在开始和结束列,然后查找它们之间的所有有效日期并为每个日期创建一行
ID name dates
466 a 2/13/2013
466 a 2/14/2013
466 a 2/15/2013
466 a 2/16/2013
466 a 2/17/2013
466 a 2/18/2013
466 a 2/19/2013
466 a 2/20/2013
答案 0 :(得分:2)
我们可以使用data.table
。转换' data.frame'到' data.table' (setDT(maint)
),按ID'分组,名称' (假设每个组合只有一行),我们得到seq
' start'结束'
library(data.table)
setDT(maint)[, .(dates = seq(start, end, by = "1 day")) , .(ID, name)]
答案 1 :(得分:1)
以下是基础R中较长的方法:
# get sequence of dates for each observation
mydates <- Map(function(x, y) seq(x, y, by="days"), as.Date(df$start), as.Date(df$end))
# get number of days for each observation
dates.length <- sapply(mydates, length)
# build a new data.frame
dfNew <- data.frame(ID=rep(df$ID, dates.length),
name=rep(df$name, dates.length),
dates=as.Date(unlist(mydates), origin=as.Date("1970-01-01"))
正如@ user2100721在评论中指出的那样,可以直接使用Map
简化seq.Date
功能:
mydates <- Map(seq.Date, as.Date(df$start), as.Date(df$end), by="days")
数据强>
df <- read.table(header=T, text="ID name start end
1 466 a 2013-02-13 2013-02-20
2 467 b 2011-02-13 2011-02-22", as.is=T)