R:如何使用dplyr作为聚合的替代方法

时间:2016-08-24 22:44:26

标签: r dplyr aggregate-functions

我有一个如下所示的数据框times

user     time
A        7/7/2010
B        7/12/2010
C        7/12/2010
A        7/12/2010 
C        7/15/2010

我正在使用aggregate(time ~ user, times, function(x) sort(as.vector(x)))来获取此信息:

user     time
A        c(7/7/2010, 7/12/2010)
B        c(7/12/2010)
C        c(7/12/2010, 7/15/2010)

问题是我在times中有超过2000万个条目,因此aggregate需要超过4个小时。有没有使用dplyr的替代方法来获取日期的排序向量?

2 个答案:

答案 0 :(得分:3)

更新后的答案:根据您的评论,这是怎么回事:

library(dplyr)

# Data (with a few additions)
times = read.table(text="user     time
A        7/7/2010
B        7/12/2010
B 7/13/2010
C        7/12/2010
A        7/12/2010 
A 7/13/2010
C        7/15/2010", header=TRUE, stringsAsFactors=FALSE)

times$time = as.Date(times$time, "%m/%d/%Y")

times
  user       time
1    A 2010-07-07
2    B 2010-07-12
3    B 2010-07-13
4    C 2010-07-12
5    A 2010-07-12
6    A 2010-07-13
7    C 2010-07-15
times %>% group_by(user) %>%
  summarise(First=min(time),
            Last=max(time),
            N = n(),
            minDiff=min(diff(time)),
            meanDiff=mean(diff(time)),
            NumDiffUniq = length(unique(diff(time))))
   user      First       Last     N        minDiff       meanDiff NumDiffUniq
1     A 2010-07-07 2010-07-13     3         1 days         3 days           2
2     B 2010-07-12 2010-07-13     2         1 days         1 days           1
3     C 2010-07-12 2010-07-15     2         3 days         3 days           1

原始答案:

我不清楚你想要完成什么。如果您只想对数据框进行排序,那么使用dplyr进行排序:

library(dplyr)

times.sorted = times %>% arrange(user, time)

如果您希望time成为每个user的日期字符串,那么您可以这样做:

times.summary = times %>% group_by(user) %>%
  summarise(time = paste(time, collapse=","))

但请注意,对于每个用户,这将导致包含日期的单个字符串。

times.summary
   user                time
1     A  7/7/2010,7/12/2010
2     B           7/12/2010
3     C 7/12/2010,7/15/2010

如果您确实希望每个单元格都是日期的向量,您可以将每个单元格设为一个列表(尽管可能有更好的方法)。例如:

times.new = times %>% group_by(user) %>%
  summarise(time = list(as.vector(time)))

times.new$time
[[1]]
[1] "7/7/2010"  "7/12/2010"

[[2]]
[1] "7/12/2010"

[[3]]
[1] "7/12/2010" "7/15/2010"

但如果您的目标是按组分析数据,那么您实际上并不需要执行上述任何操作。您可以使用基础,dplyrdata.table函数按组执行任何分析,而无需先对数据进行排序。

答案 1 :(得分:0)

根据 eipi10 dplyr解决方案以及 nrussell 的建议,我使用data.table编写了以下解决方案。

首先,您需要格式化变量times

times$time = as.Date(times$time, "%m/%d/%Y")

然后您需要使用以下内容将times转换为data.table:

library(data.table)
times <- as.data.table(times)

覆盖times对我的目的很有用,但您可能想要实例化一个新变量。将数据帧格式化为data.table后,只需执行以下操作:

new.times <- times[, 
                    .(first = min(time),
                      last = max(time),
                      n = .N,
                      meandiff = mean(diff(time)),
                      mindiff = min(diff(time)),
                      numdiffuniq = length(unique(diff(time))),
                      by='user')]

在具有128G RAM的linux虚拟机上运行并使用1000个样本,经过的运行时间为0.43秒。

有关data.table的更多信息,请参阅this tutorial