繁体   English   中英

如何基于数据帧中的其他值比较当前行和上一行的值,而R中没有循环

[英]How to compare values from current and previous rows based on other values in data frame without loops in R

我有一个日志文件转换为带有如下数据的数据框:

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。 分组是此人在当前时间的类别(行从最新到最新排列)。 计数是用户当天发生的事件的计数。 测试是我要填充值的列。

我的主要目标是只为每个用户获取构成此数据框的那些行,在其第一次更改为某个数字(不等于3)之前具有Group = 3。我想在Test列中标记此行,然后求和由每个用户计数此行的值。

我尝试使用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

有没有办法做到所有这些没有循环? 还是有解决整个问题的更好方法?

如果我正确理解了您的问题(并且很难理解),则应该执行以下操作(使用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))

否则,您可以使用更复杂的Messenger:

eventsToAnalyze %>%
    group_by(client) %>%
    filter(cummax(abs(group - 3)) <= 0) %>%
    summarize(total = sum(Count))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM