2015-04-20 2 views
7

У меня есть следующие data.frameКомбинирование (вставка) столбцы

Tipo Start End Strand Accesion1 Accesion2 
1 gene 197 1558  +  <NA> SP_0001 
2 CDS 197 1558  + NP_344554  <NA> 
3 gene 1717 2853  +  <NA> SP_0002 
4 CDS 1717 2853  + NP_344555  <NA> 
5 gene 2864 3112  +  <NA> SP_0003 
6 CDS 2864 3112  + NP_344556  <NA> 

Есть несколько значений «типо», такие как тРНК, область, экзон или рРНК, но я заинтересован только в объединении этих двух генные и CDS

и я хотели бы получить следующую

Start End Accesion1 Accesion2 
1 197 1558 NP_344554 SP_0001 

, но только тогда, когда значения начала и конца гена и C совпадают. Я пытался использовать выбрать, организовать и мутировать с dplyr, но это своего рода сложный для меня, чтобы избавиться от ВПЛ

+1

Вы, возможно, потребуется предоставить немного больше информации, о том, 'ген/CDS' происходит в парах или нет. Неясно, потому что вы упоминали, что существуют другие значения «тРНК, область, экзон» и т. Д. Предположим, если 'df1 $ Start [6] <- 2964', что будет ожидаемым результатом для примера набора данных – akrun

+0

Да, они попадают парами Решение, которое вы дали, похоже, работает очень хорошо. Потому что некоторые дополнительные Tipo присутствуют, некоторые NA появляются, но я могу легко отбросить их с помощью complete.cases Я искал решение с dplyr, просто потому, что мне это нравится. Но решение (вы удалили?) отлично работает –

+1

Не могли бы вы проверить, работает ли эта библиотека 'data.table ', setDT (df1) [, id: = cumsum (Tipo ==' gene ')] [, list (Accesion1 = na.omit (Accesion1), Accesion2 = na.omit (Accesion2)), list (id, Start, End)] ' – akrun

ответ

4

dplyr версия с summarize_each:

DF %>% 
    group_by(Start, End) %>% 
    summarise_each(funs(max), Accesion1, Accesion2) 

Производит:

Source: local data frame [3 x 4] 
Groups: Start 

    Start End Accesion1 Accesion2 
1 197 1558 NP_344554 SP_0001 
2 1717 2853 NP_344555 SP_0002 
3 2864 3112 NP_344556 SP_0003 

Предполагает AccessionX varibles являются характер (не работает с коэффициентом), а также при условии, что Партии Start End содержат только два значения: по одному для Tipo и Gene, как в вашем наборе данных.

+0

Я не знаю, почему, но я не понимаю. a sapply (df, class) говорит мне, что Accesion1 и 3 являются символами. Но я получаю это Начало Конец Accesion1 Accesion2 1 197 1558 NA NA 2 1717 2853 NA NA 3 2864 3112 NA NA 4 3196 4311 NA NA 5 4382 4951 NA NA 6 4952 8461 NA NA 7 8519 8785 Н.А. Н. А. 8 8778 9146 NA NA 9 9151 9273 NA NA 10 9266 10534 NA NA –

+1

Я считаю 'summarise_each (фаны (макс = макс (., na.rm = TRUE)), Accesion1, Accesion2)' могут быть необходимы – akrun

+0

Да, akrun, вы в порядке –

3

Вот решение с использованием aggregate():

df <- data.frame(Tipo=c('gene','CDS','gene','CDS','gene','CDS'), Start=c(197,197,1717,1717,2864,2864), End=c(1558,1558,2853,2853,3112,3112), Strand=c('+','+','+','+','+','+'), Accesion1=c(NA,'NP_344554',NA,'NP_344555',NA,'NP_344556'), Accesion2=c('SP_0001',NA,'SP_0002',NA,'SP_0003',NA)); 
df2 <- df[df$Tipo%in%c('gene','CDS'),c('Start','End','Accesion1','Accesion2')]; 
aggregate(df2[,c('Accesion1','Accesion2')], df2[,c('Start','End')], function(x) x[!is.na(x)]); 
## Start End Accesion1 Accesion2 
## 1 197 1558 NP_344554 SP_0001 
## 2 1717 2853 NP_344555 SP_0002 
## 3 2864 3112 NP_344556 SP_0003 

Предвычисление df2 необходимо в Если в исходном data.frame есть не-генные строки без CDS; для правильной агрегации только строк гена и CDS, не-генные не-CDS-строки должны быть исключены из x и by. (Конечно, ваш пример данных содержит только строки генных и CDS, так что это не является технически необходимым для примера данных.)

Это решение делает предположение о том, что всякий раз, когда две строки имеют одинаковые Start и End значения, то они должны быть гена/CDS (в отличие от гена/гена или CDS/CDS).

+0

Спасибо за комментарий. Я не проверял свое решение для всех случаев, поскольку OP упомянул, что он работает (на основе комментариев). – akrun

+0

Мне тоже нравится этот ответ. Спасибо –

2

Вот один из возможных способов. Вы выбираете строки с геном и CDS. Затем вы группируете свои данные с помощью Start и END. Могут быть группы START/END с 1 или 3+ строками. Поэтому вы хотите, чтобы вы выбрали группы START/END с двумя строками. Кроме того, вы хотите убедиться, что у вас есть как ген, так и CDS (length(unique(Tipo)) == 2). И, наконец, вы берете не-NA элемент в Accesion1 и Accesion 2.

filter(df, Tipo %in% c("gene", "CDS")) %>% 
group_by(Start, End) %>% 
filter(n() == 2 & length(unique(Tipo)) == 2) %>% 
summarise(Accesion1 = Accesion1[!is.na(Accesion1)], 
      Accesion2 = Accesion2[!is.na(Accesion2)]) 

Вот псевдо пример.

mydf <- structure(list(Tipo = structure(c(2L, 1L, 2L, 1L, 2L, 2L), .Label = c("CDS", 
"gene"), class = "factor"), Start = c(197, 197, 1717, 1717, 2864, 
2864), End = c(1558, 1558, 2853, 2853, 3112, 3112), Strand = structure(c(1L, 
1L, 1L, 1L, 1L, 1L), .Label = "+", class = "factor"), Accesion1 = structure(c(NA, 
1L, NA, 2L, NA, 3L), .Label = c("NP_344554", "NP_344555", "NP_344556" 
), class = "factor"), Accesion2 = structure(c(1L, NA, 2L, NA, 
3L, NA), .Label = c("SP_0001", "SP_0002", "SP_0003"), class = "factor")), .Names = c("Tipo", 
"Start", "End", "Strand", "Accesion1", "Accesion2"), row.names = c(NA, 
-6L), class = "data.frame") 


    Tipo Start End Strand Accesion1 Accesion2 
1 gene 197 1558  +  <NA> SP_0001 
2 CDS 197 1558  + NP_344554  <NA> 
3 gene 1717 2853  +  <NA> SP_0002 
4 CDS 1717 2853  + NP_344555  <NA> 
5 gene 2864 3112  +  <NA> SP_0003 
6 gene 2864 3112  + NP_344556  <NA> 


filter(mydf, Tipo %in% c("gene", "CDS")) %>% 
group_by(Start, End) %>% 
filter(n() == 2 & length(unique(Tipo)) == 2) %>% 
summarise(Accesion1 = Accesion1[!is.na(Accesion1)], 
      Accesion2 = Accesion2[!is.na(Accesion2)]) 

# Start End Accesion1 Accesion2 
#1 197 1558 NP_344554 SP_0001 
#2 1717 2853 NP_344555 SP_0002 
+0

@akrun Я немного ржавый. Интересно, что приведенный выше пример разъясняет вашу мысль. Пожалуйста, дайте мне знать, если мне не хватает вашей точки. – jazzurro

+1

Да, это уточняет мою точку – akrun

+0

Означает ли это, что мой data.frame должен содержать факторы ?. Мой фактически не содержит факторов. Это простой data.frame, и ваш код не работает. –

4

Вы можете попробовать

library(data.table) 
setDT(df1)[, id:=cumsum(Tipo == 'gene')][, 
    list(Accesion1=na.omit(Accesion1), Accesion2=na.omit(Accesion2)) , 
           list(id, Start, End)] 
Смежные вопросы