根据下一行R的值选择行对

问题描述 投票:0回答:2

我有一个看起来像这样的df:

ID   value
1     A
2     C
3     A
4     B
5     C
6     B
7     A
8     B

我需要获取成对的行的子集,其中第一行的值为A,然后是行的值为B。结果应如下所示:

ID  value
3    A
4    B
7    A
8    B

感谢您的帮助!

r subset criteria
2个回答
1
投票

dplyr中,我们可以使用laglead获取上一个和下一个值。

library(dplyr)

df %>%  
  filter(value == "A" & lead(value) == "B" | value == "B" & lag(value) == "A")

#  ID value
#1  3     A
#2  4     B
#3  7     A
#4  8     B

类似地在data.table中,我们可以使用shift

library(data.table)

setDT(df)[value == "A" & shift(value, type = "lead") == "B" | 
          value == "B" & shift(value) == "A"]

数据

df <- structure(list(ID = 1:8, value = structure(c(1L, 3L, 1L, 2L, 
3L, 2L, 1L, 2L), .Label = c("A", "B", "C"), class = "factor")), 
class = "data.frame", row.names = c(NA, -8L))

0
投票

这是我不太优雅的解决方案。我使用sapply()手动遍历行,然后使用ifelse()查找所需的对AB。因此,如果下一个值是A,则B在该对中,但是对于具有TRUE的行,它仅给出A,因此我进行了第二个条件检查B是否在该对中。我一直在寻找B的先前值,如果它是A,那么我们有一对。结果,我得到具有res值的向量(新列)T/F。现在,我要做的就是只选择带有T的行。最后是一些化妆品。

df$res <- sapply(1:nrow(df), function(x) ifelse((df[x,2]=='A' & df[x+1,2]=='B') | (df[x,2]=='B' & df[x-1,2]=='A'),TRUE,FALSE))
    df <- df[df$res==T,]
    df$res <- NULL
    df <- df[complete.cases(df),]
    df
      ID value
    3  3     A
    4  4     B
    7  7     A
    8  8     B
© www.soinside.com 2019 - 2024. All rights reserved.