删除R中的数据框行,并匹配多行

时间:2016-09-15 12:06:44

标签: r dataframe grepl

我的数据框看起来像这样:

content                                                ChatPosition
This is a start line                                   START
This is a middle line                                  MIDDLE
This is a middle line                                  MIDDLE
This is the last line                                  END
This is a start line with a subsequent middle or end   START
This is another start line without a middle or an end  START
This is a start line                                   START
This is a middle line                                  MIDDLE
This is the last line                                  END

content <- c("This is a start line" , "This is a middle line" , "This is a      middle line" ,"This is the last line" ,
         "This is a start line with a subsequent middle or end" , "This is     another start line without a middle or an end" ,
         "This is a start line" , "This is a middle line" , "This is the last line")
ChatPosition <- c("START" , "MIDDLE" , "MIDDLE" , "END" , "START" ,"START" , "START" ,"MIDDLE" , "END")
df <- data.frame(content, ChatPosition)

我想删除包含开头的行,但前提是下一行在ChatPosition列中不包含MIDDLE或END。

content                                                ChatPosition
This is a start line                                   START
This is a middle line                                  MIDDLE
This is a middle line                                  MIDDLE
This is the last line                                  END
This is a start line                                   START
This is a middle line                                  MIDDLE
This is the last line                                  END

nrow(df)
jjj <- 0

for(jjj in 1:nrow(df))
{
  # Check of a match of two STARTS over over multiple lines.

 if (df$ChatPosition[jjj]=="START" && df$ChatPosition[jjj+1]=="START")

   {
    print(df$content[jjj])
    }

} 

我能够使用上面的代码打印出我要删除的两行我想知道删除这些行的最优雅的解决方案是什么?

如果这里有正确的方法,或者是否有一个可以更容易地完成此类事情的库,那么嵌套也是一个for?

此致 乔纳森

3 个答案:

答案 0 :(得分:3)

使用grep。您可以将此解决方案与真实数据集上的for循环进行比较以获得速度

start_indices = grep("START",ChatPosition)
end_indices = grep("END",ChatPosition)

match_indices = sapply(end_indices,function(x) tail(start_indices[(start_indices-x)<0],1) )
match_indices
# [1] 1 7
del_indices = setdiff(start_indices,match_indices)
del_indices
# [1] 5 6
DF_subset = DF[-del_indices,]
DF_subset
                     # content ChatPosition
# 1       This is a start line        START
# 2      This is a middle line       MIDDLE
# 3 This is a      middle line       MIDDLE
# 4      This is the last line          END
# 7       This is a start line        START
# 8      This is a middle line       MIDDLE
# 9      This is the last line          END

答案 1 :(得分:2)

这应该适合你。

df[!(as.character(df$ChatPosition) == "START" & 
   c(tail(as.character(df$ChatPosition), -1), "END") == "START"), ]

                     content ChatPosition
1       This is a start line        START
2      This is a middle line       MIDDLE
3 This is a      middle line       MIDDLE
4      This is the last line          END
7       This is a start line        START
8      This is a middle line       MIDDLE
9      This is the last line          END

[]中的第一个参数返回一个逻辑向量,告诉R要保留哪些行。我使用tail(, -1)获取df$ChatPosition的下一个观察结果进行比较。请注意,有必要将df$ChatPosition转换为第二行中的字符,以便连接&#34; END&#34;在最终位置,因为df$ChatPosition是因子变量。

答案 2 :(得分:1)

另一种选择:

library(dplyr)
filter(df, !(ChatPosition == "START" & lead(ChatPosition) == "START"))

给出了:

#                     content ChatPosition
#1       This is a start line        START
#2      This is a middle line       MIDDLE
#3 This is a      middle line       MIDDLE
#4      This is the last line          END
#5       This is a start line        START
#6      This is a middle line       MIDDLE
#7      This is the last line          END