如何使用dplyr替代聚合

问题描述 投票:1回答:2

我有一个看起来像这样的数据框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的替代方法可以让我获得日期的排序向量?

r dplyr aggregate-functions
2个回答
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函数按组执行任何分析,而无需先对数据进行排序。


0
投票

基于eipi10dplyr解决方案和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.43s。

有关数据表的更多信息,请参见this tutorial

© www.soinside.com 2019 - 2024. All rights reserved.