Удаление определенных строк из фрейма данных
У меня есть кадр данных, например:
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 и day.
Например, я хотел бы удалить строки, где sub = '1' и day = '2' и sub = 3 и day = '4'. Как я могу это сделать?
Я понимаю, что я могу указать номера строк, но это нужно применять к огромному фреймворку данных, который будет утомительным для прохождения и идентификация каждой строки.
Ответы
Ответ 1
DF[ ! ( ( DF$sub ==1 & DF$day==2) | ( DF$sub ==3 & DF$day==4) ) , ] # note the ! (negation)
Или если sub является фактором, предложенным вашим использованием котировок:
DF[ ! paste(sub,day,sep="_") %in% c("1_2", "3_4"), ]
Также можно использовать подмножество:
subset(DF, ! paste(sub,day,sep="_") %in% c("1_2", "3_4") )
(И я одобряю использование which
в ответе Дирка при использовании "[", хотя некоторые утверждают, что он не нужен.)
Ответ 2
Это сводится к двум различным шагам:
- Выясните, когда ваше условие истинно, и, следовательно, вычислите вектор логических значений или, как я предпочитаю, их индексы, обернув его в
which()
- Создайте обновленный
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>
Ответ 3
Вот решение вашей проблемы с использованием функции dplyrfilter
.
Хотя вы можете передать свой фрейм данных в качестве первого аргумента любой функции dplyr, я использовал оператор %>%
, который направляет ваш фрейм данных к одной или нескольким функциям dplyr (в данном случае просто отфильтруйте).
Если вы немного знакомы с dplyr, шпаргалка очень удобна.
> 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
Ответ 4
Одно простое решение:
cond1 <- df$sub == 1 & df$day == 2
cond2 <- df$sub == 3 & df$day == 4
df <- df[!(cond1 | cond2),]