2014-09-30 9 views
6

Ich habe einen data.frame dat, der meine normalen Daten speichert und Gruppen werden durch ID definiert.R: Filtere zwei data.frames für doppelte Werte in zwei Spalten und nach Gruppen

data <- structure(list(NAME = structure(c(1L, 1L, 2L), .Label = c("NAME1", "NAME2"), class = "factor"), ID = c(23L, 23L, 57L), REF_YEAR = c(1920L, 1938L, 1869L), SURV_YEAR = c(1938L, 1962L, 1872L), VALUE = c(20L, 40L, 34L)), .Names = c("NAME", "ID", "REF_YEAR", "SURV_YEAR","VALUE"), class = "data.frame", row.names = c(NA, -3L)) 

    NAME ID REF_YEAR SURV_YEAR VALUE 
1 NAME1 23  1920  1938 20 
2 NAME1 23  1938  1962 40 
3 NAME2 57  1869  1872 34 

Und ich habe eine zweite data.frame, dat_q die ich dat

dat_q <- structure(list(NAME = structure(1:2, .Label = c("NAME1", "NAME2"), class = "factor"), ID = c(23L, 57L), REF_YEAR = c(1934L, 1866L), SURV_YEAR = c(1938L, 1868L), VALUE = structure(1:2, .Label = c("A", "B"), class = "factor")), .Names = c("NAME", "ID", "REF_YEAR", "SURV_YEAR", "VALUE"), class = "data.frame", row.names = c(NA, -2L)) 

    NAME ID REF_YEAR SURV_YEAR VALUE 
1 NAME1 23  1934  1938  A 
2 NAME2 57  1866  1868  B 

Meine Frage vergleichen möchte: Wie konnte ich alle Zeilen in dat_q löschen, die einen gleichen Wert in den Spalten enthalten REF_YEAR oder SURV_YEAR als in den gleichen Spalten von dat (in den Beispieldaten 1938)? Dies sollte durch Gruppe angewandt werden (wie durch ID definiert ist) und nicht über die gesamten data.frame

Am Ende meiner Abtastdaten verwenden würde dies aus dem Ergebnis seiner Filterung dat_q

NAME ID REF_YEAR SURV_YEAR VALUE 
2 NAME2 57  1866  1868  B 

EDIT kommenden

Hier sind einige andere Beispieldaten, mit denen der von @thelatemail bereitgestellte Code nicht funktioniert. Und ich kann nicht herausfinden, warum, dat_q sollte ausgefiltert werden, weil es einen genau gleichen Wert als dat enthält.

data <- structure(list(NAME = structure(c(1L, 1L, 1L), .Label = "NAME1", class = "factor"), ID = c(226L, 226L, 226L), SURV_YEAR = c(2009L, 2010L, 2012L), REF_YEAR = c(2008L, 2009L, 2011L), VALUE = c(-7L, -37L, -51L)), .Names = c("NAME", "ID", "SURV_YEAR", "REF_YEAR", "VALUE"), class = "data.frame", row.names = c(NA, -3L)) 

    NAME ID SURV_YEAR REF_YEAR VALUE 
1 NAME1 226  2009  2008 -7 
2 NAME1 226  2010  2009 -37 
3 NAME1 226  2012  2011 -51 

dat_q <- structure(list(NAME = structure(1L, .Label = "NAME1", class = "factor"), ID = 226L, REF_YEAR = 2010L, SURV_YEAR = 2011L, VALUE = structure(1L, .Label = "-X", class = "factor")), .Names = c("NAME", "ID", "REF_YEAR", "SURV_YEAR", "VALUE"), class = "data.frame", row.names = c(NA, -1L)) 

    NAME ID REF_YEAR SURV_YEAR VALUE 
1 NAME1 226  2010  2011 -X 

Antwort

5

Ich mag by in der Basis R für herauszufinden, die Logik dieser Art von Problem heraus. Dies funktioniert, aber vielleicht ein bisschen langsam sein:

do.call(rbind,by(
    dat_q, 
    dat_q$ID, 
    function(x) { 
    subdata <- data[data$ID==x$ID,] 
    x[!(x$REF_YEAR %in% subdata$REF_YEAR | x$SURV_YEAR %in% subdata$SURV_YEAR),] 
    } 
)) 

# NAME ID REF_YEAR SURV_YEAR VALUE 
#57 NAME2 57  1866  1868  B 

A data.table Lösung mit der gleichen Logik folgend kann schneller sein:

library(data.table) 
setDT(dat_q) 
setDT(data) 
dat_q[ 
    , 
    .SD[!(REF_YEAR %in% data$REF_YEAR[data[,ID==.BY]] | 
      SURV_YEAR %in% data$SURV_YEAR[data[,ID==.BY]])], 
    by=ID 
] 

# ID NAME REF_YEAR SURV_YEAR VALUE 
#1: 57 NAME2  1866  1868  B 

Mit data.table, ich glaube, Sie auch es auf diese Weise tun können . Nach data.tables zum Umwandeln

# using 1.9.3+, just remove `by=.EACHI` if you're using <= 1.9.2 
setkey(data, ID) 
setkey(dat_q, ID) 

idx = data[dat_q, any(c(i.REF_YEAR, i.SURV_YEAR) %in% c(REF_YEAR, SURV_YEAR)), by=.EACHI]$V1 
dat_q[!idx] 
#  NAME ID REF_YEAR SURV_YEAR VALUE 
# 1: NAME2 57  1866  1868  B 

Wir führen eine verbinden, und auf jede passende Reihe von data zu dat_q, auf den Schlüsselspalten entsprechen, berechnen wir den Ausdruck in j. Das gibt uns den logischen Wert, den wir brauchen, um später die Teilmenge dat_q zu indexieren.

+0

Ich glaube nicht, dass Sie die '[data [, ID ==. BY]] 'Teil –

+0

@DavidArenburg brauchen - muss ich die Teile im Vergleich zu den passenden IDs sicher beschränken? Verweise auf "Daten" werden nicht automatisch in die "von" Gruppen subsettiert. – thelatemail

+0

Danke @thelatemail! Während dies für einige meiner Daten funktioniert, kann ich nicht herausfinden, warum es nicht alles in meinen Daten gibt. Ich habe eine Bearbeitung veröffentlicht und neue Beispieldaten hinzugefügt, mit denen es nicht funktioniert. Es sollte 'dat_q' herausgefiltert werden, da 2011 in beiden Datensamples erscheint. – kurdtc