每行的R计算从满足特殊条件的行之前的行中的一列的值的总和

时间:2014-02-15 17:33:52

标签: r performance loops apply

我正在使用R.我有一个超过400K行的大数据集。以下是重现5行类似数据帧的代码:

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

我可以通过for循环实现这一点,但是它花费了太多时间,我知道不建议在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等功能可能会有用,但到目前为止,我无法应用它们。

提前感谢您的建议!

1 个答案:

答案 0 :(得分: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按另一个向量中的组分解向量,然后将函数应用于每个组。