![](/img/trans.png)
[英]R Date time conversion - lapply and unlist is converting to days after the epoch
[英]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
:
df2
從日期的先后df$start
以df$stop
在每一行df
。 這里, lapply
用於遍歷的各行df
和cases
重復每一行,以匹配length
所得到的日期的序列組成。 然后使用rbind
按行組合這些數據幀中的每一個。 aggregate
(從stats
包),這df2
按日期(即Var1
),並sum
了cases
。 使用您的數據:
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
一種方式填補與丟失日期0
的cases
是采取從上述解決方案的匯總結果和創建日期跨越的日期范圍的新序列。 這將為新輸出創建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.