根据列中两行之间的距离选择因子

use*_*727 2 r dplyr

我试图从下面的数据框中选择id,其中num列中的值为 2,相隔至少 2行.换句话说,给定以下数据框:

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)
Run Code Online (Sandbox Code Playgroud)

如何选择id变量,使得2的值至少由一行隔开?

我正在寻找的过程的结果将选择id 1,因为2的值被至少一行(在该示例中为2行)分开.谢谢.

此外,下面的解决方案似乎不适用于以下示例:

df <- data.frame(
  id=c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4),
  num=c(1,2,1, 1,2,2, 1,1,1,2,2,1, 1,1,1,2,2,1, 1,2,1,2,2,2)
)     
df$id<-as.factor(df$id) 
Run Code Online (Sandbox Code Playgroud)

同样,结果应该只是id 1.我只想根据ID找到数字2被另一个2乘以一行或多行的任何实例.

Fra*_*ank 6

data.table我会使用data.table包:

library(data.table)
setDT(df)

df[num == 2, .N > 1L && any(diff(.I) > 2L), by=id]

   id    V1
1:  1  TRUE
2:  2 FALSE
3:  3 FALSE
Run Code Online (Sandbox Code Playgroud)

工作原理:语法是DT[i, j, by]

  • i 子集行
  • 然后by将剩余的行分组
  • 然后j计算

在里面j我们有.I,为了方便存储行号; 和.N,by组中的行数.所以要提取ID V1 == TRUE,我们可以做到res[V1 == TRUE, id].或者,整个操作可以链接为

df[num == 2, .N > 1L && any(diff(.I) > 2L), by=id][V1 == TRUE, id]

[1] 1
Levels: 1 2 3
Run Code Online (Sandbox Code Playgroud)

base或dplyr基础R中的(几乎)类似物

sapply(split(df$num == 2, df$id), function(x){
  w = which(x)
  length(w) > 1L && any(diff(w) > 2L) 
})

    1     2     3 
 TRUE FALSE FALSE 
Run Code Online (Sandbox Code Playgroud)

后者也适用于dplyr

library(dplyr)

df %>% group_by(id) %>% summarise(x = {
  w = which(num == 2)
  length(w) > 1L && any(diff(w) > 2L) 
})

# A tibble: 3 x 2
      id     x
  <fctr> <lgl>
1      1  TRUE
2      2 FALSE
3      3 FALSE
Run Code Online (Sandbox Code Playgroud)