【问题标题】:Remove a data frame row in R with a match over multiple Rows删除 R 中与多行匹配的数据框行
【发布时间】:2016-09-15 12:06:44
【问题描述】:

我的数据框如下所示:

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 或者是否有一个库可以更轻松地完成这种类型的事情?

问候 乔纳森

【问题讨论】:

    标签: r dataframe grepl


    【解决方案1】:

    使用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
    

    【讨论】:

    • 感谢 Osssan,这也是一个有用的解决方案,使用 grep 欢呼
    【解决方案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 转换为第二行中的字符,以便在最终位置连接“END”,因为df$ChatPosition 是一个因子变量。

    【讨论】:

    • 感谢 Imo 是一个非常好的和优雅的(非常 R)解决方案。我已经尝试过了,它给出了所需的结果。非常感谢。
    【解决方案3】:

    另一种选择:

    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
    

    【讨论】:

      猜你喜欢
      • 2022-08-03
      • 2011-10-02
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      • 2012-06-15
      • 2011-12-16
      相关资源
      最近更新 更多