我需要从包含组的数据集创建(带有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,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
我的数据框包括变量组和V1。在每个组内,V1指定一个运行索引(可以从1开始,也可以不从1开始)。
我想创建一个看起来像rolling_index的新索引变量。此变量将同一组中的行和连续的V1值分组,从而创建新的滚动索引。这个新索引必须是连续的组。如果组内的行数不均匀(例如组2),则最后一行获得其自己的滚动索引值。
答案 0 :(得分: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'),如示例所示,滚动索引的创建更容易
cumsum(!!df$V1 %%2)
#[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
答案 1 :(得分: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