Вопрос по replace, r, dataframe – ошибка перевода (перекодировки) в r

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

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

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

Кроме того, чтобы избавиться от имен строк, просто сделайтеrownames(mydf) <- NULL. Josh O'Brien
Самым простым решением для вас может быть просто редактироватьx = xlate[x] вx = xlate[as.character(x)]так как это бит, который вызывает ошибку. (Thex являются векторами класса 'factor', и целые значения фактора (а не связанные строки символов) используются в индексации.) Josh O'Brien

Ваш Ответ

4   ответа
1

вектором соответствия, который является & quot; символом & quot; учебный класс:

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

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

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

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)

Создатьmatrix с замененными значениями (в этом случае преобразование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 является вектором, поэтому преобразуйте его обратно в data.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

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

4

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

t(apply (mydf1, 1, atgc))

Использоватьsapplyзатем либо используйте:

stringsAsFactors=FALSE when creating your data frame, i.e.

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

(thanks @joran) or

Change the last line of your function to: x = xlate[as.vector(x)]

Error: User Rate Limit ExceededrecodeError: User Rate Limit ExceededcarError: User Rate Limit ExceededatgcError: User Rate Limit Exceeded
Error: User Rate Limit ExceededsapplyError: User Rate Limit ExceededstringsAsFactors = FALSEError: User Rate Limit Exceeded
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), тогда как фрейм данных будет представлять собой список векторов только из миллионов элементов каждый.

Похожие вопросы