2012-04-27 4 views
5

Вот небольшой пример:перевода (перекодировки) ошибка в г

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) 

Входной кадр данных

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 

Функция

# 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 

Проблема, переменный ток не eaqual до 12 в выход скорее 11, аналогично для других. Просто беспорядок!

(Exta: Кроме того, я не знаю, как избавиться от rownames.)

+2

Простейшим решением для вас может быть просто отредактировать 'x = xlate [x]' to 'x = xlate [as.character (x)]', так как это бит, вызывающий ошибку. («X» являются векторами класса «factor», а в индексировании используются целые значения фактора (а не связанные строки символов).) –

+2

Кроме того, чтобы избавиться от имен ростов, просто введите 'rownames (mydf) <- NULL'. –

ответ

4

Просто используйте apply и транспонировать:

t(apply (mydf1, 1, atgc)) 

Чтобы использовать sapply, то либо использование:

  1. stringsAsFactors=FALSE при создании вашей информационной системы, то есть

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

    (спасибо @joran) или

  2. Изменение последней строки вашей функции: x = xlate[as.vector(x)]

+0

Я думаю, что 'sapply' будет работать, если они используют' stringsAsFactors = FALSE', чтобы избежать факторов, но я думаю, что это, вероятно, лучше. – joran

+0

@JohnCLK. Вы также можете посмотреть функцию 'recode' в пакете' car', которая делает то, что, как я думаю, вам нужна функция 'atgc'. – BenBarnes

1

The `функцией соответствия может использовать аргументы фактора с вектором целевого соответствия, что является "характер" класс:

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

Таким образом, вам нужно предоставить только значения замены для каждой отдельной буквы в матрице, без необходимости двойной проверки на m ake уверен, что вы рассмотрели все комбинации и правильно их соответствовали, хотя в вашем примере комбинации ограничены.

Определить список со значениями и их заменой:

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

Определить функцию замены с использованием gsub()

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

Создать матрицу с замененными значениями (в данном случае, преобразование mydf1 в матрицу возвращенной значащие значения для gsub(), но вы должны проверить, работает ли это с любыми другими данными перед продолжением)

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

Значения в mymat все еще находятся в том порядке, в котором они первоначально появились, так "AC" = "12" и "CA" = "21", поэтому изменить их порядок (и преобразовывать их в числовые значения)

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

Объект ansVec является вектор, поэтому преобразуйте его обратно в данные.рама

(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 

Для этой ситуации другие ответы определенно быстрее. Однако, поскольку операции по замене становятся более сложными, я думаю, что это решение может принести определенные выгоды. Однако одним из аспектов этого метода будет не проверка строки "ATTGCG" как для "ATT", так и для "TTG".

0

На самом деле, я думаю, вы хотите представить свои исходные векторы как факторы, потому что они представляют собой конечный набор уровней (ДНК-динуклеотидов), а не произвольные значения символов.

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) 

Аналогичным образом, «11» является уровнем фактора, а не числом одиннадцать. Таким образом, отображение между уровнями

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") 

и «повторного уровня» одной переменной

levels(X1) <- xlate 

Для повторного уровня все столбцы кадра данных,

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

Использование sapply не подходит, потому что это создает матрицу (символа), даже если вы назвали ее outdataframe. Различие может быть действительно важным для данных SNP, которые это могло бы представлять, поскольку миллионы SNP на 1000 образцов в качестве матрицы будут реализованы одним вектором длины, длинным, чем самый длинный вектор R может хранить (по модулю большая векторная поддержка, вводимая в R-devel), тогда как кадр данных будет списком векторов только миллионов элементов каждый.