2016-04-14 1 views
0

Ich habe zwei Datenrahmen und möchte die animals Spalte in table1 durch die animals Spalte in table2 filtern, während die mehreren Kategorien von Tieren in table1 für Katze und Hund zu halten. Das Endergebnis sollte genauso aussehen wie table1, aber mit "Löwe" entfernt. Es sollte immer noch zwei "Katze" und zwei "Hund" geben.Filtering ein Datenrahmen von Namen in einem anderen Datenrahmen während mehreren Kategorien beibehalten

Ich bin mir nicht sicher, wie ich das als Neuling angehen soll. Ich habe das Gefühl, die Antwort beinhaltet die match Funktion oder eine Art von Join? Ich würde eine dplyr oder reshape2 Methode bevorzugen, wenn möglich, vor allem, wenn es eine Möglichkeit gibt, eine dplyr Join-Funktion zu verwenden. Ich bin auch nicht sehr erfahren mit der Basisfunktion merge. Hier

ist der Code für die beiden Datenrahmen:

table1 <- data.frame(id=c(1:7), animal=c("cat","cat","dog","dog","parakeet","lion","duck")) 

table2 <- data.frame(id=c(1:4), animal=c("cat","dog","parakeet","duck")) 

Antwort

0

Sie können dies tun, mit semi_join in dplyr, denen

 return all rows from ‘x’ where there are matching 
     values in ‘y’, keeping just columns from ‘x’. 

     A semi join differs from an inner join because an inner join 
     will return one row of ‘x’ for each matching row of ‘y’, 
     where a semi join will never duplicate rows of ‘x’. 

Aber zuerst, konvertieren Sie Ihre Daten, so dass die Spalten, die wie Zeichenfolgen aussehen (aber tatsächlich Faktoren sind) tatsächlich Zeichenfolgen sind. Sie können dies durch table1[] <- lapply(table1, as.character) und table2[] <- lapply(table2, as.character) tun. Oder, wenn Sie einen data.frame schaffen, durch

table1 <- data.frame(id=c(1:7), animal=c("cat","cat","dog","dog","parakeet","lion","duck"), 
        stringsAsFactors=FALSE) 
table2 <- data.frame(id=c(1:4), animal=c("cat","dog","parakeet","duck"), 
        stringsAsFactors=FALSE) 

Dann können Sie tun

library(dplyr) 
semi_join(table1, table2, by = "animal") 

geben

id animal 
1 1  cat 
2 2  cat 
3 3  dog 
4 4  dog 
5 5 parakeet 
6 7  duck 

Wenn Sie dies nicht tun (dh, wenn Sie verbinden Sie sich auf einen Faktor) der Code wird eine Warnung geben, weil table1 und table2 Faktoren haben, nicht Strings. Diese Warnung sollte nicht ignoriert werden, da bei einigen Versionen von dplyr die Nötigung für Zeichen inkonsistent ist. Bevor Sie *join Funktionen in dplyr verwenden, konvertieren Sie Ihre Daten.frame Faktor Spalten in Zeichen.

ps

Sie auch %in innerhalb filter verwenden könnte das gleiche Ergebnis table1 %>% filter(animal %in% table2$animal)

+0

'semi_join' gibt mir inkonsistente Ergebnisse hier (also eigentlich ein anderes Ergebnis zu geben, wenn der Code ein zweites Mal ausgeführt wird), aber nie die gewünschten, die es so aussehen mag ... Buggy, so scheint es. – alistaire

+0

Inkonsistent zwischen Aufrufen auf den gleichen Daten oder ...? – jaimedash

+0

Ja. Ich habe ein paar andere Pakete dazwischen aktualisiert, aber das ist die einzige Änderung. Es gibt hier ein Problem. – alistaire

4

Sie einfach %in% wie diese verwenden:

table1[table1$animal %in% table2$animal,] 

    id animal 
1 1  cat 
2 2  cat 
3 3  dog 
4 4  dog 
5 5 parakeet 
7 7  duck 
1

Mit data.table

library(data.table) 
setDT(table1)[table2[-1], on = "animal"] 
# id animal 
#1: 1  cat 
#2: 2  cat 
#3: 3  dog 
#4: 4  dog 
#5: 5 parakeet 
#6: 7  duck