繁体   English   中英

R取消列出并相乘(日期间隔)

[英]R unlist and multiply (date intervals)

试图计算两个日期之间的案件数,有一个表,其中包含一个数字和时间间隔,我想创建带有日期和案件总数的输出表。 简单(且已解决)的问题是:

 df <- data.frame(person = c("A", "B", "C"), start = c("2014-01-01", "2014-01-03", "2014-01-04"), stop = c("2014-01-02", "2014-01-06", "2014-01-04") )
 df

 f1 = function() {  #keeping dates
   as.data.frame(table(unlist(apply(df[-1], 1, 
                                    function(x) as.character(seq(as.Date(x[1], "%Y-%m-%d"), 
                                                                 as.Date(x[2], "%Y-%m-%d"), "1 day"))))))}
 f1()

它会返回

        Var1 Freq
1 2014-01-01    1
2 2014-01-02    1
3 2014-01-03    1
4 2014-01-04    2
5 2014-01-05    1
6 2014-01-06    1

我需要的是用这样的输入数据来汇总第一列

 df <- data.frame(cases = c(5, 2, 2), start = c("2014-01-01", "2014-01-03", "2014-01-04"), stop = c("2014-01-02", "2014-01-06", "2014-01-04") )

它应该返回

        Var1 cases
1 2014-01-01    5
2 2014-01-02    5
3 2014-01-03    2
4 2014-01-04    4
5 2014-01-05    2
6 2014-01-06    2

也许甚至没有取消上市的案例,我每天可能会用什么来计算案例数量? 如果日期在开始和结束之间是有效的,但是在数据中没有任何出现,则有什么方法可以显示0值

编辑

爱潮的答案就是我需要的-唯一缺少的一点是例如获得0和

df <- data.frame(cases = c(5, 2, 2), 
start = c("2014-01-01", "2014-01-04", "2014-01-04"), 
stop = c("2014-01-02", "2014-01-06", "2014-01-04") )

要得到

        Var1 x
1 2014-01-01 5
2 2014-01-02 5
3 2014-01-03 0
4 2014-01-04 4
5 2014-01-05 2
6 2014-01-06 2

这是与f1一致的解决方案:

f2 <- function(df) {
  df2 <- do.call(rbind, lapply(1:nrow(df), function(i) {
    Var1 <- as.character(seq(as.Date(df$start[i],format="%Y-%m-%d"),
                             as.Date(df$stop[i],format="%Y-%m-%d"),"day"))
    cases <- rep(df$cases[i],length(Var1))
    data.frame(Var1,cases)
  }))
  aggregate(df2[,-1], by=list(Var1=df2[,1]), FUN=sum)
}

f2

  1. 构建数据帧df2从日期的先后df$startdf$stop在每一行df 这里, lapply用于遍历的各行dfcases重复每一行,以匹配length所得到的日期的序列组成。 然后使用rbind按行组合这些数据帧中的每一个。
  2. 然后aggregate (从stats包),这df2按日期(即Var1 ),并sumcases

使用您的数据:

f2(df)
##        Var1 x
##1 2014-01-01 5
##2 2014-01-02 5
##3 2014-01-03 2
##4 2014-01-04 4
##5 2014-01-05 2
##6 2014-01-06 2

一种方式填补与丢失日期0cases是采取从上述解决方案的汇总结果和创建日期跨越的日期范围的新序列。 这将为新输出创建Var1列。 然后,将案件从旧结果复制到与日期匹配的新输出即可:

f2 <- function(df) {
  df2 <- do.call(rbind, lapply(1:nrow(df), function(i) {
    ## note that we do not convert to characters here because we want to use these later to form the sequence
    Var1 <- seq(as.Date(df$start[i],format="%Y-%m-%d"),
                as.Date(df$stop[i],format="%Y-%m-%d"),"day")
    cases <- rep(df$cases[i],length(Var1))
    data.frame(Var1,cases)
  }))
  df2 <- aggregate(df2[,-1], by=list(Var1=df2[,1]), FUN=sum)
  ## sort previous result by date
  df2 <- df2[order(df2[,1]),]
  ## create new sequence spanning range
  Var1 <- as.character(seq(df2[1,1],df2[nrow(df2),1],"day"))
  ## create cases of zeros matching Var1 in length
  cases <- rep(0,length(Var1))
  ## copy over cases from previous result that matches date
  cases[na.omit(match(as.character(df2[,1]),Var1))] <- df2[,2]
  ## output as data frame
  data.frame(Var1,cases)
}

在更新的数据上:

f2(df)
##        Var1 cases
##1 2014-01-01     5
##2 2014-01-02     5
##3 2014-01-03     0
##4 2014-01-04     4
##5 2014-01-05     2
##6 2014-01-06     2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM