如何为R中的特定值添加序列
我在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
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