簡體   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