Keep rows with specific string and the following row

Viewed 69

This is my data frame

df <- data.frame(
  id = 1:14,
  group_id = c(rep(1:2, each = 3), rep(3:4, each = 4)),
  type = rep("A", 14), stringsAsFactors = FALSE)

df[c(2,4,8,12),"type"] <- "B"

   id group_id type
1   1        1    A
2   2        1    B
3   3        1    A
4   4        2    B
5   5        2    A
6   6        2    A
7   7        3    A
8   8        3    B
9   9        3    A
10 10        3    A
11 11        4    A
12 12        4    B
13 13        4    A
14 14        4    A

I'd like to keep all rows with type B as well as the following row.

I could do...

B <- which(df$type=="B")
afterB <- B+1
df_sel <- df[c(B, afterB), ]
df_sel <- df_sel[order(df_sel$id),]
df_sel

...to get what I want.

   id group_id type
2   2        1    B
3   3        1    A
4   4        2    B
5   5        2    A
8   8        3    B
9   9        3    A
12 12        4    B
13 13        4    A

How can this be done in a more generic way.

3 Answers

Another way, very similar to what you do but in one step and without the need to reorder:

df_sel <- df[rep(which(df$type=="B"), e=2)+c(0, 1), ] 
df_sel
   # id group_id type
# 2   2        1    B
# 3   3        1    A
# 4   4        2    B
# 5   5        2    A
# 8   8        3    B
# 9   9        3    A
# 12 12        4    B
# 13 13        4    A

Using lag from dplyr

library(dplyr)
df[df$type == "B" | lag(df$type == "B", default = FALSE), ]

#   id group_id type
#2   2        1    B
#3   3        1    A
#4   4        2    B
#5   5        2    A
#8   8        3    B
#9   9        3    A
#12 12        4    B
#13 13        4    A

using grep will provide a row index of all instances of B - rows; concatenate (c()) this with rows + 1 to select from df will work.

rows <- grep("B", df[, "type"])
df[sort(c(rows, rows + 1)), ]

gives:

   id group_id type
2   2        1    B
3   3        1    A
4   4        2    B
5   5        2    A
8   8        3    B
9   9        3    A
12 12        4    B
13 13        4    A
Related