我正在尝试使用dplyr
或DT来确定在第一次出现值之后,任何后续值是否小于给定值。
所以如果我有一个如下数据框,
df2 <- data.frame(id=c(1,1,1,1,1,2,2,2,2,3,3,3,3,3,3),
num=c(1,2,1,1,2,1,1,1,2,2,1,1,1,2,2))
df2$id <- as.factor(df2$id)
我想找到第一次出现2之后出现次数小于2的id。例如,这会获取id 1,因为第二行中有2,但是对于那个id,后续行少于2)。
有什么想法吗?
答案 0 :(得分:4)
听起来像?Position
对我的工作,虽然我不确定你想要的输出是什么:
library(data.table)
setDT(df2)
df2[, Position(I,num==2) < Position(I,num < 2,right=TRUE,nomatch=FALSE), by=id]
# id V1
#1: 1 TRUE
#2: 2 FALSE
#3: 3 TRUE
df2[, Position(I,num==2) < Position(I,num < 2,right=TRUE,nomatch=FALSE), by=id][,id[V1]]
#[1] 1 3
#Levels: 1 2 3
答案 1 :(得分:3)
data.table
的解决方案。应该选择你的示例ids 1和3中的顺便说一句,因为id 3以2开头,下一个值为1。
#first chain removes all rows for each group up to and including the first 2
#second chain returns the unique ids if a number less than 2 occurs
setDT(df2)[, .SD[-(1:which(num == 2)[1]), ], by = 'id'][which(num < 2), .(id = unique(id))]
输出:
id
1: 1
2: 3
DF2
> df2
id num
1: 1 1
2: 1 2
3: 1 1
4: 1 1
5: 1 2
6: 2 1
7: 2 1
8: 2 1
9: 2 2
10: 3 2
11: 3 1
12: 3 1
13: 3 1
14: 3 2
15: 3 2
答案 2 :(得分:2)
这是使用split-apply方法的基本R版本。
levels(df2$id)[sapply(split(df2$num, df2$id),
function(i) if(any(tail(i, -which.max(i==2)) < 2)) TRUE else FALSE)]
[1] "1" "3"
我使用levels
确保订单符合split
。 if
中的决策函数使用any
对使用tail
和which.max
切片的矢量的截断版本进行比较。