2014-02-15 46 views
1

我使用R.我有一個大的數據集超過400K行。這裏是重現5個系類似的數據幀的代碼:R爲每一行計算一個總和取值的行之前,滿足特殊條件

Date = as.Date(c("2013-01-03", "2013-01-03", "2013-01-04", "2013-01-04", "2013-01-05")) 
CustomerID = as.factor(c("A", "B", "A", "C", "A")) 
PurchaseNS = c(13, 14, 12, 8, 10) 
df = data.frame(Date, CustomerID, PurchaseNS) 

> df 
     Date CustomerID PurchaseNS 
1 2013-01-03   A   13 
2 2013-01-03   B   14 
3 2013-01-04   A   12 
4 2013-01-04   C   8 
5 2013-01-05   A   10 

我需要的是額外新增一欄,對於一個每行等於以前購買該客戶的總和。所以,最後我想獲得一個數據幀:

> df 
     Date CustomerID PurchaseNS previousPurchases 
1 2013-01-03   A   13     0 
2 2013-01-03   B   14     0 
3 2013-01-04   A   12    13 
4 2013-01-04   C   8     0 
5 2013-01-05   A   10    25 

我能做到這一點與循環,但它需要太多的時間,我知道,但不建議在R.

使用循環
for (i in 1:nrow(df)) { 
    df[i, 4] = sum(subset(df, df$CustomerID == df$CustomerID[i] & df$Date < df$Date[i])$PurchaseNS) 
} 

我也嘗試過使用sapply,但代碼最終看起來與上面類似,並且也花費了太多時間。

sapply(1:nrow(df), function(i) df[i, 4] = 
    sum(subset(df, df$CustomerID == df$CustomerID[i] & df$Date < df$Date[i])$Purchase)) 

我猜,功能,如bywithcumsumapply可能是有用的,但到目前爲止,我沒有能運用它們。

在此先感謝您的建議!

回答

2

你可以試試:

df$prevPurch <- ave(
    df$PurchaseNS, df$CustomerID, 
    FUN=function(x) cumsum(c(0, head(x, -1))) 
) 

主要生產:

#   Date CustomerID PurchaseNS prevPurch 
# 1 2013-01-03   A   13   0 
# 2 2013-01-03   B   14   0 
# 3 2013-01-04   A   12  13 
# 4 2013-01-04   C   8   0 
# 5 2013-01-05   A   10  25 

ave休息了由一組向量在另一個向量,然後應用的功能,每個組。

+0

我正在研究一個有點類似'tapply'的解決方案,但是這更好! – Jota

+0

@Frank,謝謝,我從SO上偷了這個。 – BrodieG

+0

非常感謝,它非常完美!我之前並不知道「大街」功能。 – Kapuha

相關問題