2011-08-18 8 views
16

У меня есть кадр данных .: напримерУдаление конкретных строк из dataframe

sub day 
1  1 
1  2 
1  3 
1  4 
2  1 
2  2 
2  3 
2  4 
3  1 
3  2 
3  3 
3  4 

и я хотел бы, чтобы удалить определенные строки, которые могут быть идентифицированы с помощью комбинации и суб день. Например, я хотел удалить строки, где sub = '1' и day = '2' и sub = 3 и day = '4'. Как я могу это сделать? Я понимаю, что я могу указать номера строк, но это нужно применять к огромному фреймворку данных, который будет утомительным для прохождения и идентификатора каждой строки.

ответ

27
DF[ ! ((DF$sub ==1 & DF$day==2) | (DF$sub ==3 & DF$day==4)) , ] # note the ! (negation) 

Или, если к югу является фактор, предложенный вашим использованием котировок:

DF[ ! paste(sub,day,sep="_") %in% c("1_2", "3_4"), ] 

Может также использовать подмножество:

subset(DF, ! paste(sub,day,sep="_") %in% c("1_2", "3_4")) 

(. И я поддерживаю использование which в ответ Дирка при использовании «[», хотя некоторые утверждают, что это не требуется)

+0

Thats the ticket. Благодарю. Что означает% в%? –

+2

Это пример инфиксного оператора, и он возвращает логический вектор, сообщающий вам, какие из элементов в первом аргументе содержатся во втором аргументе. См. Соответствие, где оно определено. –

+0

@BondedDust и здесь –

16

Это сводится к двум различным шагам:

  1. Выяснить, когда ваше условие истинно, и, следовательно, вычислить вектор Булевых, или, как я предпочитаю, их индексы, обернув его в which()
  2. Создайте обновленный data.frame, исключив индексы с предыдущего шага.

Вот пример:

R> set.seed(42) 
R> DF <- data.frame(sub=rep(1:4, each=4), day=sample(1:4, 16, replace=TRUE)) 
R> DF 
    sub day 
1 1 4 
2 1 4 
3 1 2 
4 1 4 
5 2 3 
6 2 3 
7 2 3 
8 2 1 
9 3 3 
10 3 3 
11 3 2 
12 3 3 
13 4 4 
14 4 2 
15 4 2 
16 4 4 
R> ind <- which(with(DF, sub==2 & day==3)) 
R> ind 
[1] 5 6 7 
R> DF <- DF[ -ind, ] 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 0 1 0 3 
    2 1 0 0 0 
    3 0 1 3 0 
    4 0 2 0 2 
R> 

И мы видим, что sub==2 имеет только один вход оставшихся с day==1.

Редактировать Условие соединения может быть сделано с «или» следующим образом:

ind <- which(with(DF, (sub==1 & day==2) | (sub=3 & day=4))) 

и вот нового полного пример

R> set.seed(1) 
R> DF <- data.frame(sub=rep(1:4, each=5), day=sample(1:4, 20, replace=TRUE)) 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 1 2 1 1 
    2 1 0 2 2 
    3 2 1 1 1 
    4 0 2 1 2 
R> ind <- which(with(DF, (sub==1 & day==2) | (sub==3 & day==4))) 
R> ind 
[1] 1 2 15 
R> DF <- DF[-ind, ] 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 1 0 1 1 
    2 1 0 2 2 
    3 2 1 1 0 
    4 0 2 1 2 
R> 
+0

нормально, я думаю, что будет работать с немного дополнительной помощи ... я нужно указать id несколько дней, поэтому я немного испробовал ваш код: ind <-which (с (Licor, day = c ('1', '16', '30', '37', '51', '52', '57 ', '58'))), но получите сообщение об ошибке. Есть идеи? –

+0

Работа над выражением для вычисления инди, вы можете найти 'help (match)' useful. –

+0

В этом ответе есть пояснения по стратегии, как применять код и какой код применять с примерами. Это было полезно. – Irwin

4

Вот решение для Вашего проблема с использованием dplyrfilter функция.

Хотя вы можете передать свой фрейм данных в качестве первого аргумента для любой функции dplyr, я использовал его оператор %>%, который передает ваш фрейм данных одной или нескольким функциям dplyr (просто фильтруйте в этом случае).

Как только вы знакомы с dplyr, cheat sheet очень удобен.

> print(df <- data.frame(sub=rep(1:3, each=4), day=1:4)) 
    sub day 
1 1 1 
2 1 2 
3 1 3 
4 1 4 
5 2 1 
6 2 2 
7 2 3 
8 2 4 
9 3 1 
10 3 2 
11 3 3 
12 3 4 
> print(df <- df %>% filter(!((sub==1 & day==2) | (sub==3 & day==4)))) 
    sub day 
1 1 1 
2 1 3 
3 1 4 
4 2 1 
5 2 2 
6 2 3 
7 2 4 
8 3 1 
9 3 2 
10 3 3 
2

один простое решение

cond1 <- df$sub == 1 & df$day == 2

cond2 <- df$sub == 3 & df$day == 4

df <- df[!cond1,]

df <- df[!cond2,]

Смежные вопросы