Usuwanie określonych wierszy z ramki danych

Mam ramkę danych np.:

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

I chciałbym usunąć konkretne wiersze, które można zidentyfikować po kombinacji sub i day. Na przykład powiedzmy, że chciałem usunąć wiersze, w których sub= '1'I day=' 2 'oraz sub=3 i day= '4'. Jak mogłem to zrobić? Zdaję sobie sprawę, że mogę określić numery wierszy, ale to musi być stosowane do ogromnej ramki danych, która byłaby żmudna, aby przejść i zidentyfikować każdy wiersz.

Author: Andre Silva, 2011-08-18

4 answers

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

Lub jeśli sub jest czynnikiem sugerowanym przez użycie cudzysłowów:

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

Można też użyć podzbioru:

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

(i popieram użycie which w odpowiedzi Dirka podczas używania " [ " , mimo że niektórzy twierdzą, że nie jest to potrzebne.)

 31
Author: 42-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 19:50:26

Sprowadza się to do dwóch odrębnych kroków:

  1. Oblicz, kiedy twój warunek jest prawdziwy, a zatem Oblicz wektor wartości logicznych lub, jak wolę, ich indeksy, owijając go w which()
  2. Utwórz zaktualizowany data.frame, wyłączając indeksy z poprzedniego kroku.

Oto przykład:

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> 

I widzimy, że {[5] } został tylko jeden wpis z day==1.

Edit warunek złożony można wykonać za pomocą " or " jako follows:

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

A oto nowy pełny przykład

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> 
 16
Author: Dirk Eddelbuettel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-18 19:36:34

Oto rozwiązanie twojego problemu za pomocą funkcjifilter dplyr .

Chociaż możesz przekazać ramkę danych jako pierwszy argument do dowolnej funkcji dplyr, użyłem jej operatora %>%, który łączy ramkę danych do jednej lub więcej funkcji dplyr (po prostu filtruj w tym przypadku).

Po zapoznaniu się z dplyr, Ściągawka jest bardzo przydatna.

> 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
 8
Author: Ken Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-09 13:15:46

Jedno proste rozwiązanie

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

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

df <- df[!cond1,]

df <- df[!cond2,]

 2
Author: Ajay Choudhary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 20:13:06