0

我想拉伸一些被压扁的记录

我有一张这样的桌子

Store     Min(Date)     Max (Date)     Status

NYC1       1/1/2013      2/1/2013      Open
NYC1       2/2/2013      2/3/2013      Closed for Inspection
Boston1    1/1/2013      2/5/2013      Open

我想把它拉伸成表格

Store       Date        Status

 NYC1       1/1/2013     Open
 NYC1       1/2/2013     Open
 .....
 NYC1       2/2/2013     Closed for Inspection
 NYC1       2/3/2013     Closed for Inspection
 ....
 Boston1    1/1/2013     Open

我知道我总是可以为此编写循环,但在尝试这样做之前,我想问一下是否有任何快速而肮脏的方法?

4

3 回答 3

4

这是一种方法:

读入您的数据并将您的日期转换为实际的日期变量:

mydf <- read.table(header = TRUE, stringsAsFactors=FALSE, 
text = "Store     Min(Date)     Max(Date)     Status
NYC1       1/1/2013      2/1/2013      Open
NYC1       2/2/2013      2/3/2013      'Closed for Inspection'
Boston1    1/1/2013      2/5/2013      Open")

names(mydf) <- c("store", "min.date", "max.date", "status")
mydf$min.date <- as.Date(mydf$min.date, format = "%m/%d/%Y")
mydf$max.date <- as.Date(mydf$max.date, format = "%m/%d/%Y")
mydf
#     store   min.date   max.date                status
# 1    NYC1 2013-01-01 2013-02-01                  Open
# 2    NYC1 2013-02-02 2013-02-03 Closed for Inspection
# 3 Boston1 2013-01-01 2013-02-05                  Open

计算“min.date”和“max.date”之间的天数差

使用该信息“扩展”您的data.frame并生成“min.date”和“max.date”之间的日期序列。此外,对 进行子集化data.frame以仅返回“store”、“date”(我们的新变量)和“status”变量。

SEQ <- mydf$max.date - mydf$min.date + 1
mydf2 <- mydf[rep(row.names(mydf), SEQ), ]
mydf2$date <- mydf2$min.date + sequence(SEQ)-1

mydf2 <- mydf2[c("store", "date", "status")]

这是输出的示例。

head(mydf2)
#     store       date status
# 1    NYC1 2013-01-01   Open
# 1.1  NYC1 2013-01-02   Open
# 1.2  NYC1 2013-01-03   Open
# 1.3  NYC1 2013-01-04   Open
# 1.4  NYC1 2013-01-05   Open
# 1.5  NYC1 2013-01-06   Open
tail(mydf2)
#        store       date status
# 3.30 Boston1 2013-01-31   Open
# 3.31 Boston1 2013-02-01   Open
# 3.32 Boston1 2013-02-02   Open
# 3.33 Boston1 2013-02-03   Open
# 3.34 Boston1 2013-02-04   Open
# 3.35 Boston1 2013-02-05   Open

您可以使用它by来验证我们所做的一切是否正确:

> with(mydf2, by(date, list(store, status), FUN = range))
: Boston1
: Closed for Inspection
NULL
----------------------------------------------------------------- 
: NYC1
: Closed for Inspection
[1] "2013-02-02" "2013-02-03"
----------------------------------------------------------------- 
: Boston1
: Open
[1] "2013-01-01" "2013-02-05"
----------------------------------------------------------------- 
: NYC1
: Open
[1] "2013-01-01" "2013-02-01"
于 2013-04-22T18:34:41.063 回答
2

使用data.table语法优雅(并假设由@Ananda 进行预处理

mydf <- read.table(header = TRUE, stringsAsFactors=FALSE, 
text = "Store     Min(Date)     Max(Date)     Status
NYC1       1/1/2013      2/1/2013      Open
NYC1       2/2/2013      2/3/2013      'Closed for Inspection'
Boston1    1/1/2013      2/5/2013      Open")

names(mydf) <- c("store", "min.date", "max.date", "status")
mydf$min.date <- as.Date(mydf$min.date, format = "%m/%d/%Y")
mydf$max.date <- as.Date(mydf$max.date, format = "%m/%d/%Y")

library(data.table)
DT <- data.table(mydf)
DT[, list(dates = seq(min.date,max.date, by = 1)) , by = list(store,status)]
于 2013-04-23T05:18:16.263 回答
0

绿魔

鉴于您的问题有 reshape 包标签,我能想到的最简单的事情就是简单地使用 melt 功能。让我们称您的 data.frame 为“foo”。下面的代码应该给你你想要的。

library(reshape)
foo.melt<-melt(foo, id.vars=c('Store','Status'))

请注意,这将创建一个带有 min.date 和 max.date 的附加列“变量”。

干杯,

丹尼

于 2013-04-23T01:09:29.423 回答