将向量中的起始位置映射到另一个向量中的终止位置

时间:2019-04-02 04:42:55

标签: r dna-sequence

我已经导出了DNA字符串中的所有起始和终止位置,现在我想将每个起始位置与每个终止位置进行映射,这两个都是向量,然后使用这些位置从DNA字符串中提取相应的子字符串顺序。但是我无法有效地遍历这两个向量来实现这一点,尤其是当它们的长度不相同时。

我尝试过不同版本的循环(例如ifelse),但是我还不能完全解决问题。

这是我解决该问题的几次尝试之一。

new = data.frame()
for (i in start_pos){
  for (j in stop_pos){
    while (j>i){
      new[j,1]=i
      new[j,2]=j
    }
     }
}

以下是我想要的结果的一个示例: 开始= c(1,5,7,9,15)停止= c(4,13,20,30,40,50)。我理想的结果理想地是将两列的数据帧映射到每个起点到其停止位置。我只想在df上添加行,这些行的起始值大于其相应的终止值(只要满足此条件,多个起始值可以具有相同的终止值),如下例所示。

 i.e first row df= (1,4)
    second row df= (5,13)
    third row df = (7, 13 )
    fourth row df = (9,13)
    fifth row df =  (15, 20)

2 个答案:

答案 0 :(得分:1)

这是一种可能的tidyverse解决方案:

library(purrr)
library(plyr)
library(dplyr)

map2用于映射两个向量(开始和停止)的值。然后,我们从这些向量中提取一个向量,然后进行unlist并将结果组合到data.frame对象中。

编辑: 使用更新的条件,我们可以执行以下操作:

start1= c(118,220, 255) 
stop1 =c(115,210,260)
res<-purrr::map2(start1[1:length(stop1)],stop1,function(x,y) c(x,y[y>x]))
res[unlist(lapply(res,function(x) length(x)>1))]
   # [[1]]
   # [1] 255 260

原始

plyr::ldply(purrr::map2(start[1:length(stop)],stop,function(x,y) c(x,y)),unlist) %>% 
   setNames(nm=c("start","stop")) %>% 
 mutate(newCol=paste0("(",start,",",stop,")"))
#  start stop  newCol
#1     1    4   (1,4)
#2     5   13  (5,13)
#3    15   20 (15,20)
#4    NA   30 (NA,30)
#5    NA   40 (NA,40)
#6    NA   50 (NA,50)

替代方法:@Marius显示了一种巧妙的方法。关键是要具有相应的长度。

plyr::ldply(purrr::map2(start,stop[1:length(start)],function(x,y) c(x,y)),unlist) %>% 
   setNames(nm=c("start","stop")) %>% 
 mutate(newCol=paste0("(",start,",",stop,")"))
  start stop  newCol
1     1    4   (1,4)
2     5   13  (5,13)
3    15   20 (15,20)

答案 1 :(得分:1)

这是一个相当简单的解决方案-最好不要使事情过于复杂,除非您确定需要额外的复杂性。开始和停止似乎已经匹配,您可能要比其他的更多,因此您可以找到最短向量的长度,并且仅使用startstop中的许多项:

start = c(1, 5, 15) 
stop = c(4, 13, 20, 30, 40, 50)

min_length = min(length(start), length(stop))

df = data.frame(
    start = start[1:min_length],
    stop = stop[1:min_length]
)

编辑:在这里阅读了您的一些评论之后,看来您的问题实际上比最初看起来要复杂得多(通过示例说明您需要的复杂程度,而又不过分复杂,总是棘手)。如果您想将每个起点与大于起点的下一终点相匹配,则可以执行以下操作:

# Slightly modified example: multiple starts
#   that can be matched with one stop
start = c(1, 5, 8)
stop = c(4, 13, 20, 30, 40, 50)

df2 = data.frame(
    start = start,
    stop = sapply(start, function(s) { min(stop[stop > s]) })
)