我有一个数据框。我希望检测连续的数字并将新列填充为1或0。
ID Val
1 a 8
2 a 7
3 a 5
4 a 4
5 a 3
6 a 1
预期输出
ID Val outP
1 a 8 0
2 a 7 1
3 a 5 0
4 a 4 1
5 a 3 1
6 a 1 0
答案 0 :(得分:7)
您可以将diff
功能与abs
结合使用,并查看结果是1
还是其他值:
d$outP <- c(0, abs(diff(d$Val)) == 1)
给出:
> d
ID Val outP
1 a 8 0
2 a 7 1
3 a 5 0
4 a 4 1
5 a 3 1
6 a 1 0
如果您只想考虑减少的连续值,可以使用:
c(0, diff(d$Val) == -1)
如果您想为每个ID
执行此操作,您也可以在基本R或 dplyr 中执行此操作:
# base R
d$outP <- ave(d$Val, d$ID, FUN = function(x) c(0, abs(diff(x)) == 1))
# dplyr
library(dplyr)
d %>%
group_by(ID) %>%
mutate(outP = c(0, abs(diff(Val)) == 1))
答案 1 :(得分:1)
我们还可以通过将之前的值与当前值
进行比较来获得更快的选项 with(df1, as.integer(c(FALSE, Val[-length(Val)] - Val[-1]) ==1))
#[1] 0 1 0 1 1 0
如果我们需要按“ID”进行分组,则有一个选项是data.table
library(data.table)
setDT(df1)[, outP := as.integer((shift(Val, fill =Val[1]) - Val)==1) , by = ID]