2016-05-10 5 views
3

Ich versuche, zwei Datensätze zu verbinden, wo eine Variable (oder Position entlang eines Genoms) in einem Datensatz in einem Bereich in der zweiten (Gen Start/Stopp-Position) passt. Positionen sind jedoch nicht eindeutig, sondern in einer zusätzlichen Spalte (Chromosom) verschachtelt. Das Gleiche gilt für die Start/Stopp-Positionen des Gens. Mein Ziel ist es, jede Position mit der entsprechenden Anmerkung und Wirkung zu verknüpfen.R, beitreten in einem Bereich vektorisiert

Zum Beispiel:

library(sqldf) 
set.seed(100) 
a <- data.frame(
    annotation = sample(c("this", "that", "other"), 3, replace=TRUE), 
    start = seq(1, 30, 10), 
    chr = sample(1:3, 3, replace=TRUE) 
) 
a$stop <- a$start + 10 
b <- data.frame(
    chr = sample(1:3, 3, replace=TRUE), 
    position = sample(1:15, 3, replace=TRUE), 
    effect = sample(c("high", "low"), 3, replace=TRUE) 
) 

Eine SQL-INNER JOIN wird mir einen Teil des Weges gibt:

df<-sqldf("SELECT a.start, a.stop, a.annotation, b.effect, b.position 
    FROM a, b 
    inner JOIN a b on(b.position >= a.start and b.position <= a.stop);") 

Aber das erklärt nicht die Wiederholung der Position pro Chromosom. Ich habe konzeptionelle Schwierigkeiten, diese in eine Schleife zu wickeln oder Funktion anzuwenden.

Ich bin nicht mit SQL verheiratet, es ist nur, wie ich zuvor ein einfacheres Problem ansprach. Ich bin mir auch nicht sicher, ob eine zusätzliche Indexspalte angebracht ist, da ich Tausende von Chromosomenwerten habe.

Meine gewünschte Ausgabe wie folgt aussehen:

df$chr<-c("NA","2","2") 
     start stop annotation effect position chr 
1  1 11  this high  3 NA 
2  1 11  this high  10 NA 
3 11 21  this low  14 2 

Wo jeder position zwischen den start und stop Punkten auf dem richtigen chr oder gegeben NA wo keine Punkte auf einem chr Spiel gesetzt worden ist.

+0

Es tut mir leid, ich den Satz verpasst. Seed, wenn ich den Code erneut ausgeführt habe. Die chr-Spalte ist Dummy-Daten, die ich angehängt habe, um zu zeigen, wonach ich suche. Ich schätze Ihre Hilfe. – smm

+0

@smm Entschuldigung, aber ich verstehe immer noch nicht, was los ist - die Spalte 'chr' im gewünschten Ergebnis ist mysteriös - ich verstehe ihre Beziehung zu' a $ chr' und 'b $ chr' nicht – eddi

+0

danke @eddi The 'position', 'start' und 'stop' sind in der 'chr'-Nummer verschachtelt, also sollte es in beiden Datasets üblich sein. – smm

Antwort

2

Ich denke, das ist, was Sie nach:

sqldf(
    "Select start, stop, annotation, effect, position, 
    case when a.chr = b.chr then a.chr else NULL end as chr 
    from b left join a 
    on b.position between a.start and a.stop 
    " 
) 
# start stop annotation effect position chr 
# 1  1 11  this high  3 NA 
# 2  1 11  this high  10 NA 
# 3 11 21  this low  14 2  
+1

Dies ist genau das, was ich suchte. Ich werde die 'chr'-Ausgabe für zukünftige Leser ändern. Das war schmerzhaft für dich und @ededi, aber es hat mir geholfen. Ich werde sicherstellen, dass meine zukünftigen Beiträge keine Telepathie erfordern. – smm

4

Die development version von data.table verbindet nicht-equi einführt, so dass für:

library(data.table) 
setDT(a) # converting to data.table in place 
setDT(b) 

b[a, on = .(position >= start, position <= stop), nomatch = 0, 
    .(start, stop, annotation, effect, x.position, chr = ifelse(i.chr == x.chr, i.chr, NA))] 
# start stop annotation effect x.position chr 
#1:  1 11  this high   3 NA 
#2:  1 11  this high   10 NA 
#3: 11 21  this low   14 2 
+1

Das ist eine spannende data.table Entwicklung! – Gregor

+0

Danke @eddi, ich merke jetzt, dass meine gewünschte Ausgabe inkohärent war. Das ist großartig, ich werde die data.table noch einmal überprüfen.Danke, dass Sie sich die Zeit für diese Frage genommen haben - diese Antwort würde funktionieren, wenn ich dann die Spalte 'chr' unterteile. – smm

+0

@smm np - bearbeitet, um dem aktuellen OP zu entsprechen – eddi