选择具有特定列匹配条件的行

ris*_*shi 8 r dataframe

我有data.frame2291行和4列,我想选择列3与下一行的第2列匹配的行,然后从下一个匹配的行再次开始,直到匹配继续,直到它停止.

我尝试使用for循环1:nrow(df),但这不完全准确,因为i(我认为)并不真正从匹配行开始.

我目前的代码是这样的:

test <- NULL 
x <- c()
y <- c()

for(i in 1:nrow(df)){
    if(df[i,3]==df[i+1,2]){
        x <- df[i,]
        y <- df[i+1,]
        i = i+1 #stuck at this
    }
    test <- rbind(test,x,y)
}
Run Code Online (Sandbox Code Playgroud)

示例数据如下所示:

X  2670000  3750000    C
X  3830000  8680000   E3
X  8680000 10120000 E1-A
X 10120000 11130079    D
X 11170079 11810079   E3
X 11810079 12810079 E2-A
X 12810079 13530079   E3
X 13530079 14050079   E3
X 14050079 15330079    A
X 15330079 16810079 E2-A
X 16810079 17690079 E2-A
Run Code Online (Sandbox Code Playgroud)

我想要的是:

X  3830000  8680000   E3
X  8680000 10120000 E1-A
X 10120000 11130079    D

X 11170079 11810079   E3
X 11810079 12810079 E2-A
X 12810079 13530079   E3
X 13530079 14050079   E3
X 14050079 15330079    A
X 15330079 16810079 E2-A
X 16810079 17690079 E2-A
Run Code Online (Sandbox Code Playgroud)

我实际上对第4列值感兴趣.在df[i,3]不等于这样的条件之后 df[i+1,2],可以更新代码以将第4列值存储在向量中吗?

例如:此示例的结果将是:

vector_1
"E3" "E1-A" "D"

vector_2
"E3" "E2-A" "E3" "E3" "A" "E2-A" "E2-A" 
Run Code Online (Sandbox Code Playgroud)

到目前为止我得到的是:

X  3830000  8680000   E3
X  8680000 10120000 E1-A
X  8680000 10120000 E1-A
X 10120000 11130079    D
X  8680000 10120000 E1-A
X 10120000 11130079    D
X 11170079 11810079   E3
X 11810079 12810079 E2-A
X 11810079 12810079 E2-A
X 12810079 13530079   E3
Run Code Online (Sandbox Code Playgroud)

如果我从第1行到我的df的最后一行,我想继续在向量中添加第4列值,只要i匹配第2 列的第3 列i+1.一旦该条件中断,下次满足相同条件时,我希望再次存储第4列值.

谢谢!

rad*_*ead 3

一种简单的方法是使用leaddplyr 包中的函数。

lead(x, n = 1L, default = NA, order_by = NULL, ...)查找向量中的“下一个”或“上一个”值。对于比较当前值之前或之后的值很有用。

这也使您可以完全避免 for 循环。由于您没有在问题中命名您的列,我将使用另一个示例:

library(dplyr)
df <- data.frame(a = 1:5, b = c(2, 999, 4, 5, 999))

print(df) # In this example, we want to keep the 1st, 3rd, and 4th rows.
     a   b
   1 1   2
   2 2 999
   3 3   4
   4 4   5
   5 5 999

matching_df <- df[df$b == dplyr::lead(df$a, 1, default = FALSE), ]
print(matching_df)
      a b
    1 1 2
    3 3 4
    4 4 5

non_matching_df <- df[df$b != dplyr::lead(df$a, 1, default = FALSE), ]
print(non_matching_df)
      a   b
    2 2 999
    5 5 999
Run Code Online (Sandbox Code Playgroud)