r语言 - 应用顺序.使用两个数据帧列的日期



我尝试使用来自展开数据框中的序列到我的数据帧,但我尝试过的任何内容都不起作用。

示例数据

library(dplyr)    
p1 <- c(1:5)
p2 <- as.Date(c("2013-01-01","2013-01-22","2014-02-01","2014-05-12","2015-02-22"))
p3 <- as.Date(c("2013-01-11","2013-01-30","2014-02-20","2014-05-22","2015-02-28"))
p4 <- c(11,9,20,11,7)
df2 <- data_frame(p1,p2,p3,p4)
names(df2) <- c("ID", "StartDate", "EndDate", "NoDays")
df2

期望的结果

ID  datelist    NoDays
1   2013-01-01   1
1   2013-01-02   1 
1   2013-01-03   1
etc..
1   2013-01-10   1
1   2013-01-11   1
2   2013-01-22   1
2   2013-01-23   1
etc.
2   2013-01-28   1
2   2013-01-29   1
2   2013-01-30   1

以下是三个代码试用 - 我尝试了所有这些变体(例如,应用程序家族的真正成员),但都失败了(即给出不同的错误消息):

代码示例 1

datelist <- seq.Date(from = df2$StartDate, to=df2$StartDate, by="days")

代码示例 2

datelist <- seq.Date(from = df2$StartDate, by="days", length.out = df2$NoDays)

代码示例 2

datelist <- apply(df2, 1, seq.Date(from = df2$StartDate, to=df2$StartDate, by="days"))

你的问题是你给seq.Date一个向量,它把一个唯一值作为fromto

与您的应用程序调用的想法相同,它应该是:

apply(df2,1,function(x) { seq.Date( as.Date(x['StartDate']), as.Date(x['EndDate']), by='days') } )

这为您提供了一个包含每个行序列的列表:

[[1]]
 [1] "2013-01-01" "2013-01-02" "2013-01-03" "2013-01-04" "2013-01-05" "2013-01-06" "2013-01-07" "2013-01-08" "2013-01-09"
[10] "2013-01-10" "2013-01-11"
[[2]]
[1] "2013-01-22" "2013-01-23" "2013-01-24" "2013-01-25" "2013-01-26" "2013-01-27" "2013-01-28" "2013-01-29" "2013-01-30"
[[3]]
 [1] "2014-02-01" "2014-02-02" "2014-02-03" "2014-02-04" "2014-02-05" "2014-02-06" "2014-02-07" "2014-02-08" "2014-02-09"
[10] "2014-02-10" "2014-02-11" "2014-02-12" "2014-02-13" "2014-02-14" "2014-02-15" "2014-02-16" "2014-02-17" "2014-02-18"
[19] "2014-02-19" "2014-02-20"
[[4]]
 [1] "2014-05-12" "2014-05-13" "2014-05-14" "2014-05-15" "2014-05-16" "2014-05-17" "2014-05-18" "2014-05-19" "2014-05-20"
[10] "2014-05-21" "2014-05-22"
[[5]]
[1] "2015-02-22" "2015-02-23" "2015-02-24" "2015-02-25" "2015-02-26" "2015-02-27" "2015-02-28"

为了获得您想要的输出,我们也应该返回 id 和 NoDays 列。

在基础 R 中,我会这样做:

getDfForDates <- function(row) {
  dseq <- seq.Date( as.Date(row['StartDate']), as.Date(row['EndDate']), by='days')
  data.frame( ID=row['ID'], datelist=dseq, NoDays=1)
}
rbindlist(
  apply(df2,1,function(x) { 
    getDfForDates(x)
  } )
)

data.table包的另一个解决方案是:

setDT(df2)
df2[, list(datelist=seq.Date( StartDate, EndDate, by='days'), NoDays=1), by=ID]

如果我没有错过一分,两者都会给出理想的结果。

我会看看我是否可以制作一个正确的 dplyr 答案,因为您似乎正在使用这个包。终于在寻找dplyr示例时发现了一个骗子,投票关闭。

我们可以很容易地做到这一点 data.table . 将"data.frame"转换为"data.table"(setDT(df2),如果"ID是唯一的",则按"ID"分组,并得到"StartDate"到"EndDate"by"ID"的seq

library(data.table)
res <- setDT(df2)[,list(datelist=seq(StartDate, EndDate, by='1 day'), 
                      NoDays = 1) , by = ID]
head(res)
#   ID   datelist NoDays
#1:  1 2013-01-01      1
#2:  1 2013-01-02      1
#3:  1 2013-01-03      1
#4:  1 2013-01-04      1
#5:  1 2013-01-05      1
#6:  1 2013-01-06      1

如果我们需要在 dplyr 中执行此操作,我们可能需要do,因为mutate不支持此类操作

library(dplyr)
df2 %>% 
   rowwise() %>%
   do(data.frame(ID= .$ID, datelist = seq(.$StartDate, 
             .$EndDate, by = '1 day'), NoDays= 1))

最新更新