组合(粘贴)列

时间:2015-04-20 15:23:32

标签: r dplyr

我有以下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>

还有更多“Tipo”值,例如tRNA,region,exon或rRNA,但我只对将这两者,基因和CDS结合感兴趣

我想得到以下内容

Start End Accesion1 Accesion2
1 197 1558 NP_344554 SP_0001

但仅当基因和CDS的起始值和结束值重合时。我尝试使用dplyr进行选择,排列和变异,但是对于我来说,摆脱NAs有点复杂

4 个答案:

答案 0 :(得分:4)

dplyrsummarize_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变量是字符(不适用于因子),以及Start End对只包含两个值的条件,Tipo和Gene各一个,如你的数据集。

答案 1 :(得分:4)

你可以尝试

library(data.table)
setDT(df1)[, id:=cumsum(Tipo == 'gene')][,
   list(Accesion1=na.omit(Accesion1), Accesion2=na.omit(Accesion2)) ,
                              list(id, Start, End)]

答案 2 :(得分: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

如果原始data.frame中存在非基因非CDS行,则必须预先计算df2;为了正确地聚合基因和CDS行,必须从xby中排除非基因非CDS行。 (当然,您的示例数据只有基因和CDS行,因此对于示例数据而言,这在技术上并不是必需的。)

此解决方案假设每当两行具有相同的StartEnd值时,它们必须是基因/ CDS对(与基因/基因或CDS / CDS相对)。 / p>

答案 3 :(得分:2)

这是一种可能的方式。您选择具有基因和CDS的行。然后,按Start和END对数据进行分组。可能存在具有1或3+行的START / END组。因此,您需要确保选择包含两行的START / END组。此外,您希望确保同时拥有基因和CDS(length(unique(Tipo)) == 2)。最后,在Accesion1和Accesion 2中使用非NA元素。

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