2012-10-22 11 views
17

Może to być proste pytanie, ale ja nadal potrzebuje pomocy za korzystanie R.Jak usunąć wiersze z data.frame, na podstawie zewnętrznej listy, używając R?

Mam data.frame (main_data), powiedzmy ..

NAMES AGE  LOC 
Jyo  23  Hyd 
Abid 27  Kar 
Ras  24  Pun 
Poo  25  Goa 
Sus  28  Kar 

życzę, aby usunąć kilka wierszy na podstawie listy nazwisk. Więc powiedzmy, że mam inną listę tabeli w następujący sposób:

NAMES_list 
Jyo 
Ras 
Poo 

więc na podstawie tej listy, jeśli któryś z nazwami pasuje do mojej powyższej „main_data” tabeli, a następnie chciałbym usunąć cały wiersz je contianing , więc wynik powinien być następujący:

NAMES AGE  LOC 
Abid 27  Kar 
Sus  28  Kar 

Czy ktoś może mi pomóc, jak osiągnąć to przy użyciu R? góry dzięki .. :)

Odpowiedz

28

Stosować %in%:

main_data2 <- main_data[ ! main_data$NAMES %in% NAMES_list, ] 
+0

Dziękuję za pomoc. Wypróbuję to. – Letin

5

Replikacja danych:

dat <- read.table(text=" 
NAMES AGE  LOC 
Jyo  23  Hyd 
Abid 27  Kar 
Ras  24  Pun 
Poo  25  Goa 
Sus  28  Kar", 
stringsAsFactors=FALSE, header=TRUE) 

remove <- c("Jyo", "Ras", "Poo") 

Proste podzbiorów:

dat[!dat$NAMES %in% remove, ] 
    NAMES AGE LOC 
2 Abid 27 Kar 
5 Sus 28 Kar 

Oto ho W to działa: Użyj kombinacji ! negacji i %in% powrócić wektor logiczną wskazującą wiersze zachować:

!dat$NAMES %in% remove 
[1] FALSE TRUE FALSE FALSE TRUE 

Pamiętam jest zaskoczony tym skonstruować pierwszy raz zobaczyłem. Dlaczego to !dat$NAMES zwraca coś użytecznego? Cóż, oczywiście wgląd polega na tym, że operator infiksowania %in% zostaje najpierw oceniony, więc ! jest po prostu logicznym operatorem NOT.

+0

... i jest oceniany jako pierwszy, ponieważ ma [precedence] (http://stat.ethz.ch/R-manual/R-patched/library/base/html/Syntax.html) przez '% any%' . – January

10

Jeśli, przez przypadek, to rzeczywiście mają data.table (w przeciwieństwie do data.frame), a data.table ma key, można użyć nie przyłączyć idiom

library(data.table) 
dat <- as.data.table(read.table(text=" 
NAMES AGE  LOC 
Jyo  23  Hyd 
Abid 27  Kar 
Ras  24  Pun 
Poo  25  Goa 
Sus  28  Kar", 
stringsAsFactors=FALSE, header=TRUE)) 

setkey(dat, NAMES) 

to.remove <- c("Jyo","Ras","Poo") 
dat[-dat[to.remove, which=TRUE]] 
# NAMES AGE LOC 
#1: Abid 27 Kar 
#2: Sus 28 Kar 

oczywiście inna twoanswers będzie również działać na data.table, ale powinno to być bardziej wydajne.


Edit

Począwszy od wersji 1.8.3 data.table, znak "!" prefiks może być użyty dla "not-joins" (patrz NEWS).

dat[!to.remove] 
    NAMES AGE LOC 
1: Abid 27 Kar 
2: Sus 28 Kar 
+2

+1 Naprawdę potrzebujemy właściwego, nie łączącego się z pracą, nie my: 'dat [-to.remove]'. Jest to dość łatwe do wdrożenia wewnętrznie, ale po prostu jeszcze tego nie mam :(To jest [FR # 1384] (https://r-forge.r-project.org/tracker/index.php?func=detail&aid= 1384 & group_id = 240 & atid = 978). –

1

Można użyć również użyć match czy są unikalne wartości w swoim main_data $ NAZW

NAMES_list <- c("Jyo","Ras","Poo") 
main_data <- main_data[-match(NAMES_list,main_data$NAMES),] 
main_data 
    NAMES AGE LOC 
2 Abid 27 Kar 
5 Sus 28 Kar 

Będzie usunąć wiersze, które dokładnie pasuje do NAMES_list z main_data $ nazwisk.

Powiązane problemy