2016-09-15 1 views
1

У меня есть кадр данных, который выглядит следующим образом:Удалить строку кадра данных в R с матчем в течение нескольких строк

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) 

Я хотел бы, чтобы удалить строки, которые содержат начало, но только если в следующей строке не содержит MIDDLE или END в столбце ChatPosition.

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]) 
    } 

} 

Я был в состоянии использовать приведенный выше код для распечатки двух линий я хочу удалить Мне интересно, что это самое элегантное решение, чтобы удалить эти строки?

Кроме того, это для вложенных, если правильный подход здесь или есть библиотека, которая может сделать этот тип вещи гораздо легче?

С уважением Джонатан

ответ

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 является фактор-переменной.

+0

Благодаря Имо действительно хороший и элегантный (Очень R). Я пробовал это, и он дает необходимый результат. Большое спасибо. –

3

Использование grep. Вы можете сравнить это решение с вашим цикл на реальных данных для скорости

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 
+0

Спасибо Osssan, это полезное решение, также используя grep cheers –

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 
Смежные вопросы