2017-11-21 3 views
2

Ich konnte keine vorherige Frage finden, die genau das beantwortet, was ich versuche.Zusammenführen von zwei Tabellen mit mehreren Bedingungen

df1

chr position effect.exposure ... 
1 12345  A    ... 
2 54321  G    ... 
2 6789  C    ... 
3 9876  D    ... 

df2

chr position effect.outcome other ... 
1 12345  A    C  ... 
2 54321  T    G  ... 
3 12314  C    A  ... 
5 12321  C    D  ... 

Das ist das allgemeine Format meiner Daten ist, mit ihm mehr anderen Spalten nicht relevant für die Verschmelzung zu sein, die aber gehalten werden muß.

Ich möchte Zeilen, die die gleiche "CHR" und "Position" streng zusammenführen, aber auch sicherstellen, dass "effect.exposure" in df1 entweder "effect.outcome" oder "other" in df2 entspricht. Wenn "effect.exposure" weder mit "effect.outcome" noch mit "other" übereinstimmt, möchte ich, dass diese Zeile gelöscht wird.

"chr" und "position" können kombiniert werden, um jeweils nur eine Spalte in den Ergebnisdaten zu haben, aber ich möchte, dass die beiden Spalten "effect" und "other" in der endgültigen Datentabelle getrennt bleiben.

Aktualisierung:

gefunden einen Weg um das Problem. Die Art und Weise, wie ich es gemacht habe, besteht darin, die beiden Datenrahmen durch "chr" und "position" zusammenzufassen.

new.df <- merge(df1, df2, by = c("chr", "position")) 

Von hier aus habe ich dann eine Teilmenge dieses Datenrahmen genommen, in den „effect.exposure“ entweder auf „effect.outcome“ oder „andere“ gleich ist.

final.df <- new.df[new.df$effect.exposure == new.df$effect.outcome | 
        new.df$effect.exposure == new.df$other, ] 

Volle Offenlegung, dies ist möglicherweise nicht die effizienteste Methode, aber es funktioniert einwandfrei.

+1

Mögliche Duplikat [R: zwei Datenrahmen zusammenführen, wenn eine von zwei Kriterien erfüllt] (https://stackoverflow.com/ Fragen/38753092/r-Merge-zwei-Daten-Frames-wenn-von-zwei-Kriterien-Übereinstimmungen) – duckmayr

Antwort

0

Dies ist eine Erweiterung einer der älteren Antworten, wobei 2 merge s durchgeführt werden, dann sind die Ergebnisse jeder Zusammenführung rbind. Das Problem mit Ihren Daten besteht darin, wie die Ergebnisse mit einer unterschiedlichen Anzahl von Spalten zusammengeführt werden. Sie können tidyr::gather und tidyr::spread verwenden, um damit umzugehen.

Ihre Daten

df1 <- structure(list(chr = c(1L, 2L, 2L, 3L), position = c(12345L, 
54321L, 6789L, 9876L), effect.exposure = c("A", "G", "C", "D" 
), misc = c("a", "b", "c", "d")), .Names = c("chr", "position", 
"effect.exposure", "misc"), class = "data.frame", row.names = c(NA, 
-4L)) 

df2 <- structure(list(chr = c(1L, 2L, 3L, 5L), position = c(12345L, 
54321L, 12314L, 12321L), effect.outcome = c("A", "T", "C", "C" 
), other = c("C", "G", "A", "D")), .Names = c("chr", "position", 
"effect.outcome", "other"), class = "data.frame", row.names = c(NA, 
-4L)) 

Erweiterung älterer Antwort

library(dplyr) 
library(tidyr) 
result1 <- inner_join(df1, df2, by=c("chr", "position", "effect.exposure" = "effect.outcome")) %>% 
       gather(key, value, -chr, -position, -effect.exposure) 

    # chr position effect.exposure key value 
# 1 1 12345    A misc  a 
# 2 1 12345    A other  C 

result2 <- inner_join(df1, df2, by=c("chr", "position", "effect.exposure" = "other")) %>% 
      gather(key, value, -chr, -position, -effect.exposure) 

    # chr position effect.exposure   key value 
# 1 2 54321    G   misc  b 
# 2 2 54321    G effect.outcome  T 

ans <- rbind(result1, result2) %>% 
      spread(key, value) 

    # chr position effect.exposure effect.outcome misc other 
# 1 1 12345    A   <NA> a  C 
# 2 2 54321    G    T b <NA> 
+0

Vielen Dank für Ihre Antwort. Ich habe es tatsächlich geschafft, einen Weg zu finden, das zu tun, was ich wollte. Vielleicht nicht die effektivste/effizienteste, aber es funktioniert für diesen Zweck. Ich habe meine ursprüngliche Frage bearbeitet, damit andere sie sehen können. – Dan

0

hoffe, das hilft!

library(dplyr) 
final_df <- df1 %>% 
    inner_join(df2, by=c("chr", "position")) %>% 
    mutate(Resp_final = if_else((as.character(effect_exposure)==as.character(effect_outcome)) | 
           (as.character(effect_exposure)==as.character(other)), 1, 0)) %>% 
    filter(Resp_final==1) %>% 
    select(-Resp_final) 
final_df 

Ausgang ist:

chr position effect_exposure col4 effect_outcome other col5 
1 1 12345    A Asdf    A  C 1234 
2 2 54321    G Abc    T  G 987 


#Sample data 
> dput(df1) 
structure(list(chr = c(1L, 2L, 2L, 3L), position = c(12345L, 
54321L, 6789L, 9876L), effect_exposure = structure(c(1L, 4L, 
2L, 3L), .Label = c("A", "C", "D", "G"), class = "factor"), col4 = structure(c(2L, 
1L, 4L, 3L), .Label = c("Abc", "Asdf", "qwerty", "xyz"), class = "factor")), .Names = c("chr", 
"position", "effect_exposure", "col4"), class = "data.frame", row.names = c(NA, 
-4L)) 

> dput(df2) 
structure(list(chr = c(1L, 2L, 3L, 5L), position = c(12345L, 
54321L, 12314L, 12321L), effect_outcome = structure(c(1L, 3L, 
2L, 2L), .Label = c("A", "C", "T"), class = "factor"), other = structure(c(2L, 
4L, 1L, 3L), .Label = c("A", "C", "D", "G"), class = "factor"), 
    col5 = c(1234L, 987L, 675L, 3456L)), .Names = c("chr", "position", 
"effect_outcome", "other", "col5"), class = "data.frame", row.names = c(NA, 
-4L)) 
+1

Vielen Dank für Ihre Antwort. Wie sich herausstellt, habe ich tatsächlich einen Weg gefunden, dies selbst zu lösen. Siehe die ursprüngliche Post bearbeiten, wenn Sie neugierig sind. – Dan

+0

Perfekt! Freut mich, dass du es selbst gelöst hast :) – Prem

Verwandte Themen