2016-04-13 5 views
6

In dem Versuch, Mismatches zwischen den zwei Datenrahmen unten zu extrahieren, habe ich bereits geschafft, einen neuen Datenrahmen zu erstellen, in dem Mismatches ersetzt werden.
Was muss ich jetzt eine Liste von Fehlpaarungen ist:Wie zwei Datenrahmen/Tabellen zu vergleichen und Daten in R extrahieren?

#  animal1 animal2 animal3 
# snp1  AA  AA  AA 
# snp2  TT  TB  00 
# snp3  AG  AG  AG 
# snp4  CA  00  00 

Ich brauche die folgende Ausgabe::

dfA <- structure(list(animal1 = c("AA", "TT", "AG", "CA"), animal2 = c("AA", "TB", "AG", "CA"), animal3 = c("AA", "TT", "AG", "CA")), .Names = c("animal1", "animal2", "animal3"), row.names = c("snp1", "snp2", "snp3", "snp4"), class = "data.frame") 
# > dfA 
#  animal1 animal2 animal3 
# snp1  AA  AA  AA 
# snp2  TT  TB  TT 
# snp3  AG  AG  AG 
# snp4  CA  CA  CA 
dfB <- structure(list(animal1 = c("AA", "TT", "AG", "CA"), animal2 = c("AA", "TB", "AG", "DF"), animal3 = c("AA", "TB", "AG", "DF")), .Names = c("animal1", "animal2", "animal3"), row.names = c("snp1", "snp2", "snp3", "snp4"), class = "data.frame") 
#> dfB 
#  animal1 animal2 animal3 
#snp1  AA  AA  AA 
#snp2  TT  TB  TB 
#snp3  AG  AG  AG 
#snp4  CA  DF  DF 

die Mismatches Um zu klären, hier werden sie als 00er markiert

structure(list(snpname = structure(c(1L, 2L, 2L), .Label = c("snp2", "snp4"), class = "factor"), animalname = structure(c(2L, 1L, 2L), .Label = c("animal2", "animal3"), class = "factor"), alleledfA = structure(c(2L, 1L, 1L), .Label = c("CA", "TT"), class = "factor"), alleledfB = structure(c(2L, 1L, 1L), .Label = c("DF", "TB"), class = "factor")), .Names = c("snpname", "animalname", "alleledfA", "alleledfB"), class = "data.frame", row.names = c(NA, -3L)) 
# snpname animalname alleledfA alleledfB 
#1 snp2 animal3  TT  TB 
#2 snp4 animal2  CA  DF 
#3 snp4 animal3  CA  DF 

Bis jetzt habe ich versucht, zusätzliche Daten aus meiner lapply Funktion zu extrahieren, die ich verwende, um die Mismatches durch Null zu ersetzen, ohne Erfolg. Ich habe auch versucht, eine ifelse-Funktion ohne Erfolg zu schreiben. Hoffe, ihr könnt mir hier helfen!

Schließlich wird dies für Datensätze mit einer Abmessung von 100 K von 1000 ausgeführt werden, so Effizienz ist ein Pro

+1

Ihre Klarstellung hergestellt werden: 'ifelse (as.matrix (DFA) == as.matrix (DFB), as.matrix (DFA), "00")' – jogo

+0

Haben die rownames von 'dfA' passen immer die rownames von 'dfB'? – lukeA

+0

@lukeA Ja, ich erstelle zwei Teilmengen, in denen sowohl die Zeilen- als auch die Spaltennamen immer übereinstimmen. – Bas

Antwort

6

Diese Frage hat data.table Tag, also hier ist mein Versuch mit diesem Paket. Der erste Schritt besteht darin, Zeilennamen in Spalten zu konvertieren, wie data.table diese nicht mögen, dann in ein langes Format nach rbind zu konvertieren und eine ID pro Datensatz zu setzen, wo mehr als ein eindeutiger Wert gefunden wird und zurück in ein breites Format konvertiert werden

library(data.table) 
setDT(dfA, keep.rownames = TRUE) 
setDT(dfB, keep.rownames = TRUE) 

dcast(melt(rbind(dfA, 
       dfB, 
       idcol = TRUE), 
      id = 1:2 
      )[, 
      if(uniqueN(value) > 1L) .SD, 
      by = .(rn, variable)], 
     rn + variable ~ .id) 

#  rn variable 1 2 
# 1: snp2 animal3 TT TB 
# 2: snp4 animal2 CA DF 
# 3: snp4 animal3 CA DF 
4

Hier ist eine Lösung array.indices einer Matrix mit:

i.arr <- which(dfA != dfB, arr.ind=TRUE) 

data.frame(snp=rownames(dfA)[i.arr[,1]], animal=colnames(dfA)[i.arr[,2]], 
      A=dfA[i.arr], B=dfB[i.arr]) 
# snp animal A B 
#1 snp4 animal2 CA DF 
#2 snp2 animal3 TT TB 
#3 snp4 animal3 CA DF 
3

Dies kann mit dplyr/tidyr mit einem ähnlichen Ansatz wie in @David Arenburg Post gemacht werden.

library(dplyr) 
library(tidyr) 
bind_rows(add_rownames(dfA), add_rownames(dfB)) %>% 
      gather(Var, Val, -rowname) %>% 
      group_by(rowname, Var) %>% 
      filter(n_distinct(Val)>1) %>% 
      mutate(id = 1:2) %>% 
      spread(id, Val) 
# rowname  Var  1  2 
# (chr) (chr) (chr) (chr) 
#1 snp2 animal3 TT TB 
#2 snp4 animal2 CA DF 
#3 snp4 animal3 CA DF