3

或者更确切地说,我怎样才能做得比我捏造的更好。

我有一个数据框,其中包含一组名称以及开始和结束日期。我想生成一个数据框,其中包含随着时间的推移组中的人数。注意,有些人还没有离开(结束日期为 NA)

这是一个示例数据集

foo<-data.frame(name=c("Bob","Sue", "Richard", "Jane"), 
        Start=as.POSIXct(c("2006-03-23 GMT", "2007-01-20 GMT", "2007-01-20 GMT", "2006-03-23 GMT")),
        End=as.POSIXct(c("2009-01-20 GMT", "NA", "2006-03-23 GMT", "NA")))

在这里,我创建了一个数据框,其日期涵盖了我想要的范围。这感觉很脏。

daterange<-data.frame(date=as.POSIXct(
                paste(
                        rep(2006:2009, each=12), 
                        "-", 
                        rep(01:12, times=4),
                        "-", 
                        1,
                        " GMT", 
                        sep="")
                        )
                )

#cheat by setting NAs to soemthing far away
foo$End[is.na(foo$End)]<-as.POSIXct(Sys.time())+(365*24*60*60)

现在我使用 ddply 来产生结果。

ddply(.data=daterange, .variable="date", function(df) {
            result=nrow(subset(foo, Start<df$date & End>df$date))
            return(result)
        })

一定有更简单的方法吗?

4

2 回答 2

3

这是使用plyr. 它直接与原始数据框一起使用foo,不需要转换NA为日期。该代码是不言自明的并且非常易读。欢迎任何意见。

dates = seq(as.POSIXct('2006-01-01'), as.POSIXct('2009-12-01'), by = "month")
count = ldply(dates, function(d) 
   with(foo, sum((Start < d) + (d < End | is.na(End)) == 2)))
data.frame(dates, count)
于 2011-07-02T12:17:51.260 回答
2

以下是您可能会发现更容易的另一种方法:

foo<-data.frame(name=c("Bob","Sue", "Richard", "Jane"), 
    Start=as.POSIXct(c("2006-03-23 GMT", "2007-01-20 GMT", "2007-01-20 GMT", "2006-03-23 GMT")),
    End=as.POSIXct(c("2009-01-20 GMT", NA, "2006-03-23 GMT", NA)))


tmp <- expand.grid(foo$name,seq.POSIXt(as.POSIXct('2006-01-01'),
               as.POSIXct('2009-12-01'),by="month"))
colnames(tmp) <- c('name','date')
foo[is.na(foo)] <- max(tmp$date) + 1

tmp1 <- merge(tmp,foo,by="name")
tmp2 <- tmp1$Start <= tmp1$date & tmp1$End >= tmp1$date
aggregate(tmp2,by=list(date=tmp1$date),sum)

我在这里的两分钱是使用seq.*而不是paste一起使用日期,ddply如果您真的一次只使用 daterange 一个元素,那将是一种尴尬的工具。我用过aggregate,但你可以用过lapply或类似的东西。

如果你真的想的话,你可以把它压缩成更少的行,但是可读性会受到影响。

于 2011-07-01T16:07:24.473 回答