2016-04-13 24 views
6

Khi cố gắng trích xuất các sự không khớp giữa hai khung dữ liệu bên dưới, tôi đã quản lý để tạo ra một khung dữ liệu mới trong đó không khớp được thay thế.
Những gì tôi cần bây giờ là một danh sách các sai lệch:Làm thế nào để so sánh hai khung/bảng dữ liệu và trích xuất dữ liệu trong 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 

Để làm rõ các sai lệch, ở đây họ được đánh dấu là 00:

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

tôi cần đầu ra sau đây:

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 

Cho đến nay tôi đã cố gắng trích xuất dữ liệu bổ sung ra khỏi chức năng lapply mà tôi sử dụng để thay thế các sự không phù hợp bằng không, mà không thành công. Tôi cũng đã cố gắng viết một hàm ifelse mà không thành công. Hy vọng các bạn có thể giúp tôi ở đây!

Cuối cùng này sẽ được chạy cho các tập dữ liệu có kích thước 100K 1000, vì vậy hiệu quả là một pro

+1

làm rõ của bạn có thể được sản xuất bởi: 'ifelse (as.matrix (DFA) == as.matrix (DFB), as.matrix (DFA), "00")' – jogo

+0

Làm rownames của 'dfA' luôn luôn phù hợp với các rownames của 'dfB'? – lukeA

+0

@lukeA có, tôi tạo hai tập con trong đó cả tên hàng và cột sẽ luôn khớp. – Bas

Trả lời

6

Câu hỏi này có thẻ data.table, vì vậy, đây là nỗ lực của tôi khi sử dụng gói này. Bước đầu tiên là chuyển đổi tên hàng thành các cột là data.table không thích những tên đó, sau đó chuyển sang định dạng dài sau rbind ing và đặt id cho mỗi tập dữ liệu, tìm vị trí có nhiều hơn một giá trị duy nhất và chuyển đổi thành định dạng rộng

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

Đây là một giải pháp sử dụng array.indices của một ma trận:

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

Điều này có thể được thực hiện với dplyr/tidyr bằng cách sử dụng phương pháp tương tự như trong bài đăng của @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 
Các vấn đề liên quan