创建跟踪每个主题完成的循环数的列

时间:2015-09-11 21:41:51

标签: r running-total

我正在处理一个数据集,该数据集计算主题对某些位置(或位置类型)的访问次数。当某个主题访问某个位置时(在我的示例中,我们会说它的位置为“X”),访问计数会为每个主题重置。

我有一个分组变量可以帮助我在“X”和“非X”位置之间进行过滤,但我想跟踪每个主题发生的序列数。

library(dplyr)
location <- c("A", "B", "X", "A", "C", "X", "A", "X", "C", "A", "B", "B", "A", "A", "X") 
group <- c(1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0)
id <- c(111, 111, 111, 111, 112, 112, 113, 113, 113, 113, 113, 114, 114, 114, 114)

df <- data.frame(id, group, location)

df <- within(df, {
    ## this produces a lot of warnings, but it achieves my desired result
    count = ave(id, group, cumsum(group == 0), id, FUN = seq)
    }) %>%
    mutate(count = ifelse(group == 0, yes = 0, no = count)) ## mark restarts

print(df)
     id location group count
 1  111        A     1     1
 2  111        B     1     2
 3  111        X     0     0
 4  111        A     1     1
 5  112        C     1     1
 6  112        X     0     0
 7  113        A     1     1
 8  113        X     0     0
 9  113        C     1     1
10  113        A     1     2
11  113        B     1     3
12  114        B     1     1
13  114        A     1     2
14  114        A     1     3
15  114        X     0     0

感谢stackoverflow,我发现了我需要在我的数据中的每个主题中生成序列所需的代码。但是,这仅保留数据的每个单独事件的运行计数。我希望能够记录计数在每个受试者数据中重置的次数,并将其保留为变量以帮助进行其他分析。

我一直在努力解决如何正确描述我所需要的东西,并且生成这样的序列并不是我在编程方面遇到过的经验。我正在处理几十万个ID,所以我不愿意尝试在R中的for循环中收集任何这些操作。有关如何以更简单和R友好的方式完成此任务的建议吗?

以下是我希望得到的一个例子:

     id location group count cycle
 1  111        A     1     1     1
 2  111        B     1     2     1
 3  111        X     0     0     0
 4  111        A     1     1     2
 5  112        C     1     1     1
 6  112        X     0     0     0
 7  113        A     1     1     1
 8  113        X     0     0     0
 9  113        C     1     1     2
10  113        A     1     2     2
11  113        B     1     3     2
12  114        B     1     1     1
13  114        A     1     2     1
14  114        A     1     3     1
15  114        X     0     0     0

此函数返回我正在寻找的内容,但我不确定它是否可以很好地扩展到实际数据:

trackCycle <- function(sequence) {
    cycle <- 1
    out <- c()
    for (i in 1:length(sequence)) {
        if(i != 1 & sequence[i] == 0) {
            cycle <- cycle + 1
            out <- c(out, 0)
        } else {
            out <- c(out, cycle)
        }
    }
    out
}

df %>%
   group_by(id) %>%
   mutate(cycle = trackCycle(count))

1 个答案:

答案 0 :(得分:1)

评论的直接解决方案:

df <- df %>%
    group_by(id) %>%
    mutate(cycle = 1 + cumsum(location == "X"))

df[df$location == "X", "cycle"] <- 0