2016-04-13 25 views
6

Nel tentativo di estrapolare le mancate corrispondenze tra i due frame di dati di seguito, sono già riuscito a creare un nuovo frame di dati in cui vengono sostituite le mancate corrispondenze.
cosa ho bisogno ora è una lista dei disallineamenti:Come confrontare due frame di dati/tabelle ed estrarre i dati in R?

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 

Per chiarire il mismatch, qui sono contrassegnati come 00:

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

mi serve il seguente output:

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 

Finora ho cercato di estrarre dati aggiuntivi dalla mia funzione lapply che uso per sostituire i disallineamenti per zero, comunque senza successo. Ho anche provato a scrivere una funzione ifelse senza successo. Spero che voi ragazzi potete aiutarmi qui!

fine questo verrà eseguita per insiemi di dati con una dimensione di 100 K per 1000, per cui l'efficienza è un pro

+1

vostro chiarimento può prodotto da: 'IfElse (as.matrix (DFAE) == as.matrix (DFB), as.matrix (DFAE), "00")' – jogo

+0

fare lo rownames di 'dfA' abbinare sempre i nomi di scena di 'dfB'? – lukeA

+0

@lukeA sì, creo due sottoinsiemi in cui entrambi i nomi di riga e colonna corrisponderanno sempre. – Bas

risposta

6

Questa domanda ha il tag data.table, quindi ecco il mio tentativo di utilizzare questo pacchetto. Il primo passo è convertire i nomi delle righe in colonne come data.table non piace a quelli, quindi convertire in formato lungo dopo rbind ing e impostare un ID per set di dati, trovare dove ci sono più di un valore univoco e riconvertire in un ampio formato

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

Ecco una soluzione che utilizza una matrice di array.indices:

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

Questo può essere fatto con dplyr/tidyr utilizzando un approccio simile come nel post di @David Arenburg.

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 
Problemi correlati