nsy*_*mms 4 r cumulative-sum dplyr
我在data.frame中有一个数字向量,如下所示.
df <- data.frame(a = c(1,2,3,4,2,3,4,5,8,9,10,1,2,1))
Run Code Online (Sandbox Code Playgroud)
我需要创建一个新列,它提供比其前任更大的条目的运行计数.生成的列向量应为:
0,1,2,3,0,1,2,3,4,5,6,0,1,0
Run Code Online (Sandbox Code Playgroud)
我的尝试是创建一个diffs的"flag"列,以便在值更大时进行标记.
df$flag <- c(0,diff(df$a)>0)
> df$flag
[1] 0 1 1 1 0 1 1 1 1 1 1 0 1 0
Run Code Online (Sandbox Code Playgroud)
然后我可以应用一些dplyr组/ sum魔法几乎得到正确的答案,除了当flag == 0时总和没有重置:
df %>% group_by(flag) %>% mutate(run=cumsum(flag))
a flag run
1 1 0 0
2 2 1 1
3 3 1 2
4 4 1 3
5 2 0 0
6 3 1 4
7 4 1 5
8 5 1 6
9 8 1 7
10 9 1 8
11 10 1 9
12 1 0 0
13 2 1 10
14 1 0 0
Run Code Online (Sandbox Code Playgroud)
我不想使用for()循环,因为我有几个这样的运行总和来计算data.frame中的几十万行.
Pie*_*une 13
这是一种方式ave:
ave(df$a, cumsum(c(F, diff(df$a) < 0)), FUN=seq_along) - 1
[1] 0 1 2 3 0 1 2 3 4 5 6 0 1 0
Run Code Online (Sandbox Code Playgroud)
我们可以得到一个分组的运行计数diff(df$a) < 0.向量中哪些位置比其前辈少.我们添加c(F, ..)到第一个位置的帐户.该向量的累积总和创建分组索引.该函数ave可以对该索引执行一个函数,我们seq_along用于运行计数.但是从1开始,我们减去1 ave(...) - 1从零开始.
类似的方法使用dplyr:
library(dplyr)
df %>%
group_by(cumsum(c(FALSE, diff(a) < 0))) %>%
mutate(row_number() - 1)
Run Code Online (Sandbox Code Playgroud)
Rol*_*and 10
你不需要dplyr:
fun <- function(x) {
test <- diff(x) > 0
y <- cumsum(test)
c(0, y - cummax(y * !test))
}
fun(df$a)
[1] 0 1 2 3 0 1 2 3 4 5 6 0 1 0
Run Code Online (Sandbox Code Playgroud)