如何在R中使用循环加速代码

时间:2016-09-06 13:26:32

标签: r loops

问题: 我有两个数据帧。 DF与付款日志:

Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   53682 obs. of  7 variables:


str(moneyDB)
 $ user_id : num  59017170 57859746 58507536 59017667 59017795 ...
 $ reg_date: Date, format: "2016-08-06" "2016-07-01" "2016-07-19" ...
 $ date    : Date, format: "2016-08-06" "2016-07-01" "2016-07-19" ...
 $ money   : num  0.293 0.05 0.03 0.03 7 ...
 $ type    : chr  "1" "2" "2" "1" ...
 $ quality : chr  "VG" "no_quality" "no_quality" "VG" ...
 $ geo     : chr  "Canada" "NO GEO" "NO GEO" "Canada" ...

这是它的结构。它只是所有交易的记录。

我还有第二个数据框:

str(grPaysDB)

Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   335591 obs. of  9 variables:
 $ reg_date      : Date, format: "2016-05-01" "2016-05-01" "2016-05-01" ...
 $ date          : Date, format: "2016-05-01" "2016-05-01" "2016-05-01" ...
 $ type          : chr  "1" "1" "1" "1" ...
 $ quality       : chr  "VG" "VG" "VG" "VG" ...
 $ geo           : chr  "Australia" "Canada" "Finland" "Canada" ...
 $ uniqPayers    : num  0 1 0 1 1 0 0 1 0 3 ...

来自第一个数据帧+零事务的Grouped数据。例如,第二个数据框中有很多行,零付款人。这就是为什么第二个数据帧比第一个更大。

我需要将列 weeklyPayers 添加到第二个数据框。每周付款人是过去7天内独特的付款人。我尝试通过循环来做,但它太久了。有没有其他矢量化的想法,如何实现这个?

weeklyPayers <- vector()
for (i in 1:nrow(grPaysDB)) {
   temp <- moneyDB %>%
      filter(
         geo == grPaysDB$geo[i],
         reg_date == grPaysDB$reg_date[i],
         quality == grPaysDB$quality[i],
         type == grPaysDB$type[i],
         between(date, grPaysDB$date[i] - 6, grPaysDB$date[i])
      )

   weeklyPayers <- c(weeklyPayers, length(unique(temp$user_id)))
}
grPaysDB <- cbind(grPaysDB, weeklyPayers)

在第二个数据框中每一行的此循环中,我在第一个数据框中找到具有正确地理位置,类型,质量和reg_date以及日期范围的行。然后我可以计算出独特付款人的数量。

2 个答案:

答案 0 :(得分:0)

我会尝试在多个列(merge)上使用c('geo', 'reg_date', 'quality', 'type'对您的数据集进行连接,并根据日期过滤结果。之后,使用summarise进行汇总。

但我不完全确定你为什么要在每笔交易中添加每周付款人。在周数(使用dplyr)汇总数据不是更具信息性或更容易。像这样:

moneyDB %>% mutate(week = date- as.POSIXlt(date)$wday) %>%
  group_by(geo, reg_date, quality, type, week) %>%
  summarise(weeklyPayers = n())

答案 1 :(得分:0)

我可能会误解,但我认为这应该相当简单,在dplyr中使用过滤器和摘要。但是,正如@ Hack-R所提到的,拥有数据集会很有帮助。但它看起来像是:

library(dplyr)
weeklyPayers <- grPaysDB %>%
   filter(date > ADD DATE IN QUESTION) %>%
   summarise(sumWeeklyPayers = sum(uniqPayers))

然后,我可能会误解。如果您的问题涉及每周的求和,那么您可能希望在timeSeries包中每天调查2周,然后使用group_by作为发生的每周变量。