我有一个日志文件转换为数据框,数据如下:
Client Date Group Count Test
C1 1.437512e+12 6 2 0
C1 1.437685e+12 3 1 0
C2 1.437685e+12 3 1 0
C2 1.437772e+12 6 1 0
C2 1.438117e+12 6 2 0
C2 1.464037e+12 3 3 0
C3 1.448662e+12 6 2 0
C3 1.451081e+12 3 5 0
C4 1.437944e+12 6 1 0
C4 1.438895e+12 3 6 0
C5 1.460581e+12 3 2 0
C5 1.460668e+12 6 2 0
C5 1.460927e+12 6 1 0
C5 1.461013e+12 3 2 0
C6 1.437685e+12 3 1 0
C6 1.437944e+12 6 1 0
C6 1.447711e+12 3 2 0
C6 1.458079e+12 3 2 0
C7 1.463000e+12 3 5 0
C7 1.463000e+12 10 1 0
C8 1.463951e+12 6 5 0
C8 1.463951e+12 3 1 0
C9 1.463346e+12 3 5 0
C9 1.464037e+12 10 1 0
C10 1.459804e+12 3 2 0
C10 1.461272e+12 3 1 0
C10 1.461877e+12 5 1 0
C10 1.462223e+12 5 1 0
C10 1.462482e+12 5 1 0
客户是数据库中人员的ID。群组是当前时刻此人的类别(行从最新到最新排序)。 Count是当天用户所做事件的计数。测试是一个我想填充值的列。
我的主要目标是为每个用户只获取那些形成此数据框的行,在其第一次更改为某个数字之前具有Group = 3,即不等于3.我想在Test列中标记这些行然后将每个用户对此行的Count值求和。
我尝试用for循环来解决这个问题:
for (i in 2:length(log$Group)){
if (log$Client[i-1] == log$Client[i]) {
if ((log$Group[i-1] == 3) & (log$Group[i] != 3)) {
log$Test[i] <- NA
}
if ((log$Group[i-1] != 3) & (log$Group[i] == 3)) {
log$Test[i] <- NA
}
if ((log$Group[i-1] == 3) & (log$Group[i] == 3)) {
if(is.na(log$Test[i-1])) {
log$Test[i] <- NA
}
}
if ((log$Group[i-1] != 3) & (log$Group[i] != 3)) {
log$Test[i] <- NA
log$Test[i-1] <- NA
}
}
}
但是在完整数据上运行此循环需要很长时间。然后我将删除所有带有NA的行。
结果如下:
Client Date Group Count Test
C2 1.437685e+12 3 1 1
C5 1.460581e+12 3 2 1
C6 1.437685e+12 3 1 1
C7 1.463000e+12 3 5 1
C9 1.463346e+12 3 5 1
C10 1.459804e+12 3 2 1
C10 1.461272e+12 3 1 1
有没有办法在没有循环的情况下完成所有这些操作?或者可能有更好的方法来解决整个问题?
答案 0 :(得分:1)
如果我理解你的问题(并且很难理解),你应该做以下的事情(使用包dplyr
):
eventsToAnalyze %>%
filter(group == 3) %>%
group_by(client) %>%
summarize(total = sum(Count))
这将过滤掉不在第3组中的行,并按客户端对Count
列中的值进行求和。
修改强>
啊,既然你已经澄清了你的问题,我就看到了问题。如果3是最低值,这应该有效:
eventsToAnalyze %>%
group_by(client) %>%
filter(cummax(group) <= 3) %>%
summarize(total = sum(Count))
否则你可以使用更混乱,但更通用:
eventsToAnalyze %>%
group_by(client) %>%
filter(cummax(abs(group - 3)) <= 0) %>%
summarize(total = sum(Count))