2012-04-27 22 views
5

Dưới đây là ví dụ nhỏ:dịch (thu âm) lỗi trong r

X1 <- c("AC", "AC", "AC", "CA", "TA", "AT", "CC", "CC") 
X2 <- c("AC", "AC", "AC", "CA", "AT", "CA", "AC", "TC") 
X3 <- c("AC", "AC", "AC", "AC", "AA", "AT", "CC", "CA") 
mydf1 <- data.frame(X1, X2, X3) 

Input khung dữ liệu

X1 X2 X3 
1 AC AC AC 
2 AC AC AC 
3 AC AC AC 
4 CA CA AC 
5 TA AT AA 
6 AT CA AT 
7 CC AC CC 
8 CC TC CA 

Chức năng

# Function 
atgc <- function(x) { 
xlate <- c("AA" = 11, "AC" = 12, "AG" = 13, "AT" = 14, 
"CA"= 12, "CC" = 22, "CG"= 23,"CT"= 24, 
"GA" = 13, "GC" = 23, "GG"= 33,"GT"= 34, 
"TA"= 14, "TC" = 24, "TG"= 34,"TT"=44, 
"ID"= 56, "DI"= 56, "DD"= 55, "II"= 66 
) 
    x = xlate[x] 
} 
outdataframe <- sapply (mydf1, atgc) 
outdataframe 
    X1 X2 X3 
AA 11 11 12 
AA 11 11 12 
AA 11 11 12 
AG 13 13 12 
CA 12 12 11 
AC 12 13 13 
AT 14 11 12 
AT 14 14 14 

Vấn đề, AC không eaqual đến 12 trong đầu ra thay vì 11, tương tự cho những người khác. Chỉ cần lộn xộn!

(exta: Ngoài ra tôi không biết làm thế nào để thoát khỏi những rownames.)

+2

Giải pháp đơn giản nhất cho bạn có thể chỉ là chỉnh sửa 'x = xlate [x]' thành 'x = xlate [as.character (x)]', vì đó là bit gây ra lỗi. ('X' là vectơ của lớp 'yếu tố', và các giá trị số nguyên của nhân tố (chứ không phải là các chuỗi ký tự liên quan) đang được sử dụng trong việc lập chỉ mục.) –

+2

Ngoài ra, để loại bỏ các rownames, chỉ cần làm' rownames (mydf) <- NULL'. –

Trả lời

4

Chỉ cần sử dụng apply và transpose:

t(apply (mydf1, 1, atgc)) 

Để sử dụng sapply, sau đó, hoặc sử dụng:

  1. stringsAsFactors=FALSE khi tạo khung dữ liệu, tức là

    mydf1 <- data.frame(X1, X2, X3, stringsAsFactors=FALSE) 
    

    (nhờ @joran) hoặc

  2. Thay đổi dòng cuối cùng của chức năng của bạn để: x = xlate[as.vector(x)]

+0

Tôi nghĩ rằng 'sapply' sẽ hoạt động nếu họ sử dụng' stringsAsFactors = FALSE' để tránh các yếu tố, nhưng tôi nghĩ điều này có lẽ tốt hơn. – joran

+0

@JohnCLK, Bạn cũng có thể xem hàm 'recode' trong gói' car', cái mà tôi nghĩ bạn muốn hàm 'atgc' làm. – BenBarnes

1

Lệnh `chức năng phù hợp có thể sử dụng đối số yếu tố với một vector phù hợp với mục tiêu đó là "nhân vật" lớp học:

atgc <- function(fac){ c(11, 12, 13, 14, 
12, 22, 23, 24, 
13, 23, 33, 34, 
14, 24, 34,44, 
56, 56, 55, 66)[ 
match(fac, 
    c("AA", "AC", "AG", "AT", 
    "CA", "CC", "CG","CT", 
    "GA", "GC", "GG","GT" , 
    "TA", "TC", "TG","TT", 
    "ID", "DI", "DD", "II")) 
       ]} 
#The match function returns an index that is designed to pull from a vector. 
sapply(mydf1, atgc) 
    X1 X2 X3 
[1,] 12 12 12 
[2,] 12 12 12 
[3,] 12 12 12 
[4,] 12 12 12 
[5,] 14 14 11 
[6,] 14 12 14 
[7,] 22 12 22 
[8,] 22 24 12 
0
Bằng cách này, bạn chỉ phải cung cấp giá trị thay thế cho từng chữ cái trong ma trận mà không phải kiểm tra lại thành m ake chắc chắn bạn đã xem xét tất cả các kết hợp và kết hợp chúng một cách chính xác, mặc dù với ví dụ của bạn, các kết hợp bị giới hạn.

Xác định danh sách với các giá trị và thay thế của họ:

trans <- list(c("A","1"),c("C","2"),c("G","3"),c("T","4"), 
    c("I","6"),c("D","5")) 

Xác định chức năng thay thế sử dụng gsub()

atgc2 <- function(myData, x) gsub(x[1], x[2], myData) 

Tạo một ma trận với các giá trị thay thế (trong trường hợp này, chuyển đổi mydf1 để một ma trận trở lại các giá trị ký tự như mong muốn cho gsub(), nhưng bạn sẽ muốn kiểm tra xem điều này có hoạt động với bất kỳ dữ liệu nào khác trước khi tiếp tục)hay không

mymat <- Reduce(atgc2, trans, init = as.matrix(mydf1)) 

Các giá trị trong mymat vẫn nằm trong thứ tự mà họ ban đầu xuất hiện, vì vậy "AC" = "12""CA" = "21", vì vậy sắp xếp lại chúng (và chuyển đổi chúng sang các giá trị số)

ansVec <- sapply(strsplit(mymat, split = ""), 
    function(x) as.numeric(paste0(sort(as.numeric(x)), collapse = ""))) 

Đối tượng ansVec là một vector, do đó, chuyển đổi nó trở lại thành một dữ liệu.frame

(mydf2 <- data.frame(matrix(ansVec, nrow = nrow(mydf1)))) 
# X1 X2 X3 
# 1 12 12 12 
# 2 12 12 12 
# 3 12 12 12 
# 4 12 12 12 
# 5 14 14 11 
# 6 14 12 14 
# 7 22 12 22 
# 8 22 24 12 

Trong trường hợp này, các câu trả lời khác chắc chắn nhanh hơn. Tuy nhiên, khi các hoạt động thay thế trở nên phức tạp hơn, tôi nghĩ giải pháp này có thể mang lại một số lợi ích. Tuy nhiên, một trong những phương pháp mà phương pháp này sẽ không giải quyết, sẽ kiểm tra chuỗi "ATTGCG" cho cả hai "ATT""TTG".

0

Thực ra, tôi nghĩ bạn muốn đại diện cho các vectơ gốc của mình là các yếu tố, vì chúng đại diện cho một tập hợp các mức hữu hạn (DNA dinucleotides) chứ không phải là các giá trị ký tự tùy ý.

lvls = c("AA", "AC", "AG", "AT", "CA", "CC", "CG", "CT", "GA", "GC", 
     "GG", "GT", "TA", "TC", "TG", "TT", "ID", "DI", "DD", "II") 
X1 <- factor(c("AC", "AC", "AC", "CA", "TA", "AT", "CC", "CC"), levels=lvls) 
X2 <- factor(c("AC", "AC", "AC", "CA", "AT", "CA", "AC", "TC"), levels=lvls) 
X3 <- factor(c("AC", "AC", "AC", "AC", "AA", "AT", "CC", "CA"), levels=lvls) 
mydf1 <- data.frame(X1, X2, X3) 

Tương tự, "11" là mức của hệ số và không phải là số mười một. Vì vậy, một ánh xạ giữa các cấp là

xlate <- c("AA" = "11", "AC" = "12", "AG" = "13", "AT" = "14", 
      "CA"= "12", "CC" = "22", "CG"= "23","CT"= "24", 
      "GA" = "13", "GC" = "23", "GG"= "33","GT"= "34", 
      "TA"= "14", "TC" = "24", "TG"= "34","TT"="44", 
      "ID"= "56", "DI"= "56", "DD"= "55", "II"= "66") 

và sẵn sàng 'tái cấp' một đơn biến

levels(X1) <- xlate 

Để tái cấp tất cả các cột của khung dữ liệu,

as.data.frame(lapply(mydf1, `levels<-`, xlate)) 

Sử dụng sapply không phù hợp, bởi vì điều đó tạo ra một ma trận (của nhân vật), mặc dù bạn đã đặt tên nó là outdataframe. Sự khác biệt có thể thực sự quan trọng đối với dữ liệu SNP mà điều này có thể đại diện, vì hàng triệu SNP trên 1000 mẫu làm ma trận sẽ được triển khai một vector dài hơn vectơ dài nhất R có thể lưu trữ (hỗ trợ vectơ lớn modulo được đưa vào R-devel), trong khi khung dữ liệu sẽ là một danh sách các vectơ chỉ có hàng triệu phần tử.