我在R中有一个带有一系列变量的data.frame
userID (numeric) var1 (factor) var2 (factor) time (character) action (character)
每个用户会话的前3列相同,可以有很多行。但是,每行time
和action
都会发生变化。
我已经尝试aggregate
将整个会话(连续行)合并为一行。
dat <- aggregate(cbind(time, action) ~ userID + var1 + var2,
data = log, FUN = paste, collapse = "|")
如果用户只出现在文件中一次,这将解决我的问题。但是,情况并非如此,上面的行将所有会话聚合为一行。
我该如何避免?如何仅汇总连续的行(会话)?
答案 0 :(得分:1)
像MrFlick所说的那样,除了使用:
创建user.session
变量
rle <- with(log, rle(as.character(interaction(user, var1, var2))))
log$user.session <- rep(seq_along(rle$lengths), rle$lengths)
对于我们凡人而言,似乎更容易理解......
答案 1 :(得分:0)
我将创建一个user.session ID,以便为给定用户/ var1 / var2的每个连续行序列分配一个唯一ID。首先,一个样本数据集
log<-data.frame(
user = rep(c(1,2,3,1,3,4), times),
var1 = factor(rep(letters[c(1,2,3,1,3,4)+7], times)),
var2 = factor(rep(letters[c(1,2,3,1,3,4)+13], times)),
time = "a",
action="b",
stringsAsFactors=F
)
现在我们添加user.session id
log$user.session<-with(log,
ave(seq_len(nrow(log)),user,var1,var2,FUN=function(x) {
cumsum(c(0,diff(x))!=1)
})
)
现在你可以做到
dat <- aggregate(cbind(time, action) ~ user + var1 + var2 + user.session,
data = log, FUN = paste, collapse = "|")
给出了
user var1 var2 user.session time action
1 1 h n 1 a|a|a|a|a b|b|b|b|b
2 2 i o 1 a|a|a b|b|b
3 3 j p 1 a b
4 4 k q 1 a|a|a b|b|b
5 1 h n 2 a|a b|b
6 3 j p 2 a|a|a|a|a|a|a b|b|b|b|b|b|b
答案 2 :(得分:0)
所以在床上我有相同的实现,即添加user.session列。我喜欢你的两个解决方案,但第二个更容易理解,这就是我选择它的原因。无论如何,这是第三种可能性
log $ user.session&lt; - cumsum(c(TRUE,diff(log $ userID)!= 0))
然后,在聚合函数中包含此列也可以解决问题。
干杯。