Combinación de datos.frame y selección de valores que son comunes en 2 Data.frames

Tengo 3 data.frames

> head(ON1) Entrez.ID Nearest.Refseq Gene.Name Tag.Count 1 11302 NM_007377 Aatk 137.48 2 11303 NM_013454 Abca1 118.09 3 11305 NM_007379 Abca2 93.56 4 11306 NM_009592 Abcb7 92.42 5 11308 NM_007380 Abi1 410.73 6 11356 NM_009598 Abl5 149.46 > head(ON2) Entrez.ID Nearest.Refseq Gene.Name Tag.Count 1 11303 NM_013454 Abca1 86.02 2 11305 NM_007379 Abca2 103.45 3 11306 NM_009592 Abcb7 95.32 4 11308 NM_007380 Abi1 313.85 5 11350 NM_009594 Abl1 116.24 6 11352 NM_009595 Abl2 155.76 > head(ON3) Entrez.ID Nearest.Refseq Gene.Name Tag.Count 1 11303 NM_013454 Abca1 69.49 2 11305 NM_007379 Abca2 82.02 3 11306 NM_009592 Abcb7 83.16 4 11308 NM_007380 Abi1 306.44 5 11350 NM_009594 Abl1 150.37 6 11355 NM_009599 Abl4 154.93 

Algunas filas son exclusivas de solo 1 data.frame (por ejemplo, row1 de ON1 ), algunas son comunes en 2 data.frames (por ejemplo, row5 de ON2 y ON3 , esta fila no existe en ON1 ) y algunas son comunes en todos los datos. marcos (por ejemplo, row2 de ON1 que es row1 en ON2 y ON3 ). La única diferencia son los valores en la última columna Tag.Count

Quiero fusionar los 3 data.frames de tal forma que obtenga solo aquellas filas en mi data.frame final que son comunes entre al menos 2 data.frames y el valor de Tag.Count que es más alto entre ellos será asignado a esa fila.

 > head(F) Entrez.ID Nearest.Refseq Gene.Name Tag.Count 1 11303 NM_013454 Abca1 118.09 2 11305 NM_007379 Abca2 103.45 3 11306 NM_009592 Abcb7 95.32 4 11308 NM_007380 Abi1 410.73 5 11350 NM_009594 Abl1 150.37 

Aquí puede ver que las filas con Entrez.ID = 11302 se eliminan, ya que solo aparecen una vez entre todos los data.frames y aquellas filas que eran comunes en al menos 2 data.frames aparecen aquí pero la puntuación Tag.Count que era máxima entre todos los data.frames están asignados a esa fila.

ACTUALIZAR

Cómo tomar promedio de filas Después de fusionar los tres conjuntos de datos, en lugar de mantener solo una fila que tenga el valor máximo de Tag.count , quiero sumr el valor de Tag.count y dividir por el número total de filas que tienen el mismo Entrez.ID . De hecho, los valores en las primeras 3 columnas son los mismos, la diferencia solo aparece en la última columna. Ejemplo:

 > head(d) Entrez.ID Nearest.Refseq Gene.Name Tag.Count 1 11302 NM_007377 Aatk 137.48 2 11303 NM_013454 Abca1 118.09 7886 11303 NM_013454 Abca1 86.02 15407 11303 NM_013454 Abca1 69.49 3 11305 NM_007379 Abca2 93.56 7887 11305 NM_007379 Abca2 103.45 

Entonces, en este caso, como 3 filas tienen Entrez.ID = Entrez.ID , los valores de Tag.count se Tag.count (118.09 + 86.02 + 69.49) y se dividirán entre 3 y la salida final contendrá solo 1 fila que tenga Entrez.ID y Tag.Count value = Sum / no.of Rows

Aquí hay una manera de combinar los tres marcos de datos. Después de combinar los tres, encontramos los valores que aparecen más de una vez. Con ese índice podemos agregar el dataframe con la función max :

 d < - do.call(rbind, list(ON1, ON2, ON3)) d1 <- do.call(paste, d[1:3]) tbl <- table(d1) > 1L indx < - d1 %in% names(tbl[tbl]) aggregate(Tag.Count ~., d[indx,], FUN=max) # Entrez.ID Nearest.Refseq Gene.Name Tag.Count # 1 11303 NM_013454 Abca1 118.09 # 2 11305 NM_007379 Abca2 103.45 # 3 11306 NM_009592 Abcb7 95.32 # 4 11308 NM_007380 Abi1 410.73 # 5 11350 NM_009594 Abl1 150.37 

Puede hacer esto en dplyr enlazando los tres juntos, filtrando los grupos con un elemento y luego seleccionando el Tag.Count superior en cada grupo.

 library(dplyr) F < - bind_rows(ON1, ON2, ON3) %>% group_by(Entrez.ID) %>% # elements are in same group if same Entrez.ID filter(n() > 1) %>% # filter out groups with 1 element top_n(1, Tag.Count) # pick highest Tag.Count from each 

En cuanto a la actualización:

preliminares

 tab < - structure( list( Entrez.ID = c(11302L, 11303L, 11303L, 11303L, 11305L, 11305L), Nearest.Refseq = structure(c(1L, 3L, 3L, 3L, 2L, 2L), .Label = c("NM_007377", "NM_007379", "NM_013454"), class = "factor"), Gene.Name = structure(c(1L, 2L, 2L, 2L, 3L, 3L), .Label = c("Aatk", "Abca1", "Abca2"), class = "factor"), Tag.Count = c(137.48, 118.09, 86.02, 69.49, 93.56, 103.45) ), .Names = c("Entrez.ID", "Nearest.Refseq", "Gene.Name", "Tag.Count"), class = "data.frame", row.names = c("1", "2", "7886", "15407", "3", "7887") ) print(tab) # Entrez.ID Nearest.Refseq Gene.Name Tag.Count # 1 11302 NM_007377 Aatk 137.48 # 2 11303 NM_013454 Abca1 118.09 # 7886 11303 NM_013454 Abca1 86.02 # 15407 11303 NM_013454 Abca1 69.49 # 3 11305 NM_007379 Abca2 93.56 # 7887 11305 NM_007379 Abca2 103.45 

dplyr forma

 library(dplyr) (res < - tab %>% group_by(Entrez.ID) %>% filter(n() > 1) %>% summarise(Means = mean(Tag.Count))) 

Resultado:

  Entrez.ID Means (int) (dbl) 1 11302 137.480 2 11303 91.200 3 11305 98.505 

data.table pura de data.table , después del comentario de David Arenburg

 library(data.table) (res < - setDT(tab)[, if(.N > 1) { .(Means = mean(Tag.Count)) }, by = Entrez.ID]) 

Resultado igual que arriba.

Deje las columnas Nearest.Refseq y Gene.Name

Dos posibles soluciones dplyr , elija una:

Asumiendo Nearest.Refseq y Gene.Name son únicos para cada Gene.Name :

 res < - tab %>% group_by(Entrez.ID) %>% summarise(Nearest.Refseq = Nearest.Refseq[1], Gene.Name = Gene.Name[1], Means = mean(Tag.Count)) 

Si no, debes hacer algo con ellos (reemplaza someFunction() !):

 res < - tab %>% group_by(Entrez.ID) %>% summarise(Nearest.Refseq = someFunction(Nearest.Refseq), Gene.Name = someFunction(Gene.Name), Means = mean(Tag.Count)) 

Editar: se dplyr enfoque mixto data.table / dplyr .