如何为R中的特定值添加序列

如何为R中的特定值添加序列,r,R,我在R中有以下数据帧 a b 1 0 2 0 3 0 4 1 5 1 6 1 7 0 8 0 9 0 10 1 11 1 所需的数据帧是 a b Flag 1 0 1 2 0 2 3 0 3 4 1 4 5 1 4 6 1 4 7 0 5 8 0

我在R中有以下数据帧

 a    b
 1    0
 2    0
 3    0
 4    1
 5    1
 6    1
 7    0
 8    0
 9    0
10    1
11    1
所需的数据帧是

 a    b     Flag
 1    0      1
 2    0      2
 3    0      3
 4    1      4
 5    1      4
 6    1      4
 7    0      5
 8    0      6
 9    0      7
10    1      8
11    1      8
顺序应更改为0,并在1中保持不变

我是按照下面的命令做的

df$flag <- with(a, match(b, unique(b)))
df$标志已更新,以说明b的第一个元素为1。感谢@tk3指出需要进行更改。
看起来您的规则是增加标志,如果b为零或者它是序列中的第一个1

这会给你答案

cumsum(1 + c(df$b[1],diff(df$b)>0) - df$b)
[1] 1 2 3 4 4 4 5 6 7 8 8
如果您只想在b为零时增加标志,可以使用
cumsum(1-df$b)
。但这不会改变系列中第一个的标志。所以我想做一个
b
的修改版本,将所有第一个设置为b=0。您可以使用
c(df$b[1],diff(df$b)>0)
来获取b从0变为1的所有位置——“第一个”。现在

将所有“第一个一”更改为零,除非它是b的第一个元素。有了这个修改后的b,我们可以使用如上所述的cumsum。我们想取一个

1-(df$b-c(df$b[1],差异(df$b)>0))=1+c(df$b[1],差异(df$b)>0)-df$b

这是我的回答

cumsum(1 + c(df$b[1],diff(df$b)>0) - df$b)
[1] 1 2 3 4 4 4 5 6 7 8 8

原始版本仅适用于df$b[1]=0。更新后的版本也适用于df$b[1]=1

以下内容似乎可以满足您的需要。
我觉得这有点复杂,但很有效

sp <- split(df, cumsum(c(0, abs(diff(df$b)))))
df2 <- lapply(sp, function(DF) {
    DF$Flag <- as.integer(DF$b != 1)
    if(DF$b[1] == 1) DF$Flag[1] <- 1 
    DF
})

rm(sp)    # clean up

df2 <- do.call(rbind, df2)
df2$Flag <- cumsum(df2$Flag)
row.names(df2) <- NULL
df2
#    a b Flag
#1   1 0    1
#2   2 0    2
#3   3 0    3
#4   4 1    4
#5   5 1    4
#6   6 1    4
#7   7 0    5
#8   8 0    6
#9   9 0    7
#10 10 1    8
#11 11 1    8

sp为什么第4行的flag=4?b=1。第10行看起来也是错误的。这就是我要生成的序列。是的。它只会在第一行1中更改。如果b列的第一个值为1,则标志应以0开头?它将以1开头,如果下一行也是1,则它将具有值1,依此类推。(1,1,0,0,0)标志将是(1,1,2,3,4)这是我需要的,你能让我理解你的代码吗?这将给答案增加一点。对于b(1,1,0,0,0),标志正在输出(0,0,1,2,3)。如果你能解决这个问题,这将是一个非常好的答案!是的,它应该输出(1,1,2,3,4),考虑到Flag是cumsum的输出,可能只是添加一个if?if(df$b[1]==1){Flag
sp <- split(df, cumsum(c(0, abs(diff(df$b)))))
df2 <- lapply(sp, function(DF) {
    DF$Flag <- as.integer(DF$b != 1)
    if(DF$b[1] == 1) DF$Flag[1] <- 1 
    DF
})

rm(sp)    # clean up

df2 <- do.call(rbind, df2)
df2$Flag <- cumsum(df2$Flag)
row.names(df2) <- NULL
df2
#    a b Flag
#1   1 0    1
#2   2 0    2
#3   3 0    3
#4   4 1    4
#5   5 1    4
#6   6 1    4
#7   7 0    5
#8   8 0    6
#9   9 0    7
#10 10 1    8
#11 11 1    8