我有一个相对较大的数据框,跨越包含2个变量的5.5M观测值,这里是一个数据样本。它包含有关用户生成综合浏览量的日期的信息。
timestamp user_id
2013-11-07 ff268cef0c29
2013-11-02 12bb7af7a842
2013-11-30 e45abb10ae0b
2013-11-06 e45abb10ae0b
2013-11-25 f266f8c9580e
请注意,数据框首先按user_id排序,然后按时间戳排序,直至
kstaord<-kstaord[order(kstaord$timestamp,kstaord$user_id),]
我的目标是创建一个索引列,它会根据用户发生的日期索引用户的所有页面视图,这应该会产生如下结果:
timestamp user_id index
2013-11-07 ff268cef0c29 1
2013-11-02 12bb7af7a842 1
2013-11-30 e45abb10ae0b 1
2013-11-06 e45abb10ae0b 2
2013-11-25 f266f8c9580e 1
到目前为止,我已尝试过for循环:
for (j in 2:nrow(kstaord)) {
if (kstaord$user_id[j]!=kstaord$user_id[j-1]) {kstaord$index[j]<-1}
else {kstaord$index[j]<-kstaord$index[j-1]+1}
if ((j %% 100000)==0) {print(".")}
}
这需要花费大量时间,但会产生不一致的结果。我找到了一个堆栈溢出线程here来处理类似的问题。我已经尝试了以下建议这个线程,我不确定(我搜索ave函数说它产生平均值):
index <- ave( 1:nrow(kstaord), kstaord$user_id, factor( kstaord$timestamp),
FUN=function(x) 1:length(x) )
然而,我无法让这个功能运行完整的过程(我正在进行R的服务器安装,目前我的连接错误,所以我不能确定这不会因为我的连接问题而发生) 。原始函数还将次要维度定义为因子,而我使用的是日期变量,因此这也可能是一个问题。
我正在寻找能够提供一致结果的解决方案,并且在我最多可以使用近24 GB RAM的服务器上运行时没有问题。
提前感谢您的帮助。
答案 0 :(得分:2)
使用data.table
:
library(data.table)
DT <- as.data.table(dat)
DT[, index := seq_len(.N), by = user_id]
timestamp user_id index
1: 2013-11-07 ff268cef0c29 1
2: 2013-11-02 12bb7af7a842 1
3: 2013-11-30 e45abb10ae0b 1
4: 2013-11-06 e45abb10ae0b 2
5: 2013-11-25 f266f8c9580e 1
答案 1 :(得分:1)
ave
替代方案。如果我理解你的问题,你不需要'timestamp'作为分组变量。使用'user_id'应该足够了。
df$index <- with(df, ave(user_id, user_id, FUN = seq_along))
df
# timestamp user_id index
# 1 2013-11-07 ff268cef0c29 1
# 2 2013-11-02 12bb7af7a842 1
# 3 2013-11-30 e45abb10ae0b 1
# 4 2013-11-06 e45abb10ae0b 2
# 5 2013-11-25 f266f8c9580e 1
是的,你是正确的ave
“中的默认函数产生平均值”(FUN = mean
)。但您可以将FUN
设置为适合您需要的任何功能。
在较大的数据集上,data.table
替代品最有可能更快(例如@agstudy提供的答案)。