按月

2013-10-11 32 views
1

線性分配金額請考慮下面的合成數據幀:按月

#Learning to enable splitting contributions spanning two months 

start = c(as.Date("2013-01-01"), as.Date("2013-02-01"), as.Date("2013-04-01"), as.Date("2013-04-16"), as.Date("2013-05-16")) 
end = c(as.Date("2013-01-31"), as.Date("2013-03-31"), as.Date("2013-04-15"), as.Date("2013-05-15"), as.Date("2013-05-31")) 
amount = c(100, 200, 50, 100, 50) 

df = data.frame(start,end,amount) 

這是收到的現金和它涉及到時間的列表。其中一些時間段爲兩個月。我想按月彙總。對於那些涉及兩個月的期限的數額,我想在兩個月之間進行線性分攤/分配。

在R中做這件事的慣用方法是什麼?

+0

可能重複的[值的平分配數跨越的時間段(http://stackoverflow.com/questions/18835463/flat-apportionment-of-values-across-time-periods) – Michele

+0

由於米歇爾。我已經閱讀了平攤分配問題的答案,並不完全確定如何將其應用於我的示例。我需要更多的指導,因爲我對R很陌生,所以還需要一些關於R思維方式中「事情已經完成」的習慣性見解。但是,謝謝你指出! –

+0

在第四行的情況下,你想要的東西分配50美元到四月和50美元可能,或者離開這一個單獨的,因爲它的總持續時間是一個月? –

回答

4

創建一個函數explode,該函數將間隔分解爲一行數據幀,每天有一行。使用Mapexplode應用於每個產生數據幀列表的間隔,每個間隔一個。接下來rbind將列表中的數據幀合併爲一個大數據幀,即by.date,每天有一行。最後彙總by.date成一排,每年/月:

library(zoo) # as.yearmon 

explode <- function(start, end, amount) { 
    dates <- seq(start, end, "day") 
    data.frame(dates, yearmon = as.yearmon(dates), amount = amount/length(dates)) 
} 
by.date <- do.call("rbind", Map(explode, df$start, df$end, df$amount)) 
aggregate(amount ~ yearmon, by.date, sum) 

的問題使用數據(假設2010年的發生被認爲是2013年),我們得到:

yearmon amount 
1 Jan 2013 100.00000 
2 Feb 2013 94.91525 
3 Mar 2013 105.08475 
4 Apr 2013 100.00000 
5 May 2013 100.00000 

更新:如果內存是一個問題,用它代替explode。它首先在explode內彙總,以使其輸出更小。此外,我們已經在DF消除dates列,因爲它是隻包括用於調試:

explode <- function(start, end, amount) { 
    dates <- seq(start, end, "day") 
    DF <- data.frame(yearmon = as.yearmon(dates), amount = amount/length(dates)) 
    aggregate(amount ~ yearmon, DF, sum) 
} 

更新2:這是另一種嘗試。它使用rowsum這是專門用於彙總總和。在我的測試中,這篇文章的數據運行速度提高了10倍。的

explode2 <- function(start, end, amount) { 
    dates <- seq(start, end, "day") 
    n <- length(dates) 
    rowsum(rep(amount, n)/n, format(dates, "%Y-%m")) 
} 
by.date <- do.call("rbind", Map(explode2, df$start, df$end, df$amount)) 
rowsum(by.date, rownames(by.date)) 
+0

我發現這個答案是最清楚的。我沒有遇到do.call,但在「花一點時間」之後,我開始明白這一點。這個答案也改善了我對函數式編程的思考,但在我真正掌握鏈接的扁平分配答案之前,我還有很長的路要走。許多感謝所有。 –