我有一个看起来像这样的数据框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
的替代方法可以让我获得日期的排序向量?
更新后的答案:根据您的评论,如何做:
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"
但是,如果您的目标是按组分析数据,那么您实际上不需要执行上述任何操作。您可以使用基函数,dplyr
或data.table
函数按组执行任何分析,而无需先对数据进行排序。
基于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.43s。
有关数据表的更多信息,请参见this tutorial。