Выберите пару строк на основе значения следующей строки R - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть 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

Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

В dplyr мы можем использовать lag и lead, чтобы получить предыдущее и следующее значения.

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"]

data

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 голосов
/ 06 апреля 2020

Вот мое не очень элегантное решение. Я вручную перебираю строки, используя sapply(), затем я использовал ifelse(), чтобы найти нужные пары AB. Таким образом, A находится в паре, если следующее значение равно B, но оно дает TRUE только для строк с A, поэтому я сделал второе условие, проверяя, есть ли B в паре. Я искал предыдущее значение B, если оно A, то у нас есть пара. В результате у меня есть вектор (новый столбец) res со значениями T/F. Теперь все, что мне нужно было сделать, это выбрать только строки с T. Наконец немного косметики c вещи.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...