R 在组上创建对的滚动索引
我需要(使用R)从包含组的数据集中创建一个成对的滚动索引。考虑下面的数据集:R 在组上创建对的滚动索引,r,R,我需要(使用R)从包含组的数据集中创建一个成对的滚动索引。考虑下面的数据集: times <- c(4,3,2) V1 <- unlist(lapply(times, function(x) seq(1, x))) df <- data.frame(group = rep(1:length(times), times = times), V1 = V1, rolling_index = c(1,1,2,2,
times <- c(4,3,2)
V1 <- unlist(lapply(times, function(x) seq(1, x)))
df <- data.frame(group = rep(1:length(times), times = times),
V1 = V1,
rolling_index = c(1,1,2,2,3,3,4,5,5))
df
group V1 rolling_index
1 1 1 1
2 1 2 1
3 1 3 2
4 1 4 2
5 2 1 3
6 2 2 3
7 2 3 4
8 3 1 5
9 3 2 5
次您可以尝试
library(data.table)
setDT(df)[, gr:=as.numeric(gl(.N, 2, .N)), group][,
rollindex:=cumsum(c(TRUE,abs(diff(gr))>0))][,gr:= NULL]
# group V1 rolling_index rollindex
#1: 1 1 1 1
#2: 1 2 1 1
#3: 1 3 2 2
#4: 1 4 2 2
#5: 2 1 3 3
#6: 2 2 3 3
#7: 2 3 4 4
#8: 3 1 5 5
#9: 3 2 5 5
或使用base R
indx1 <- !duplicated(df$group)
indx2 <- with(df, ave(group, group, FUN=function(x)
gl(length(x), 2, length(x))))
cumsum(c(TRUE,diff(indx2)>0)|indx1)
#[1] 1 1 2 2 3 3 4 5 5
正如在文章中提到的,如果某些组的“V1”列不是从“1”开始的,我们可以从“组”中获取序列,然后像上面那样执行cumsum
cumsum(!!with(df, ave(seq_along(group), group, FUN=seq_along))%%2)
#[1] 1 1 2 2 3 3 4 5 5
可能有一种更简单的方法,但您可以:
rep_each <- unlist(mapply(function(q,r) {c(rep(2, q),rep(1, r))},
q=table(df$group)%/%2,
r=table(df$group)%%2))
df$rolling_index <- inverse.rle(x=list(lengths=rep_each, values=seq(rep_each)))
df$rolling_index
#[1] 1 1 2 2 3 3 4 5 5
用连续的V1
值代表每个滚动索引组。但是,这不是您在数据框中显示的内容,例如从第6行到第7行。这不是错误。在第2组中,我将前两个观察值(第5行和第6行)用于新的分组(滚动指数=3)。因为我在这个组中只剩下一个观察值,它有自己的滚动索引值(4)。请显示您想要的输出。我想创建一个看起来像滚动索引的变量。这个索引的模式是什么?您希望每个组中的每两行都有一个新的索引,因此下面是使用base R;-)的更好方法@凯斯格:这很简单,但我们没有早点发现。
rep_each <- unlist(mapply(function(q,r) {c(rep(2, q),rep(1, r))},
q=table(df$group)%/%2,
r=table(df$group)%%2))
df$rolling_index <- inverse.rle(x=list(lengths=rep_each, values=seq(rep_each)))
df$rolling_index
#[1] 1 1 2 2 3 3 4 5 5