r data.frame 旋转和添加行
r data.frame pivoting and adding rows
我有一个 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
我们可以使用data.table
。将'data.frame'转换为'data.table'(setDT(maint)
),按'ID'分组,名称'(假设每个组合只有一行),我们得到[= 'start' 的 13=] 到 'end' .
library(data.table)
setDT(maint)[, .(dates = seq(start, end, by = "1 day")) , .(ID, name)]
这是一个较长的基础 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)
我有一个 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
我们可以使用data.table
。将'data.frame'转换为'data.table'(setDT(maint)
),按'ID'分组,名称'(假设每个组合只有一行),我们得到[= 'start' 的 13=] 到 'end' .
library(data.table)
setDT(maint)[, .(dates = seq(start, end, by = "1 day")) , .(ID, name)]
这是一个较长的基础 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)