检查向量中的值是否在不同长度向量中的值范围内

时间:2014-07-15 19:01:14

标签: r bioinformatics

所以我在R工作并且拥有一个包含基因组位置的载体的大型数据框:

2655180
2657176
2658869 

第二个具有一系列位置和类似基因的数据框:

chr1    100088228   100162167   AGL
chr1    107599438   107600565   PRMT6
chr1    115215635   115238091   AMPD1
chr1    11850637    11863073    MTHFR
chr1    119958143   119965343   HSD3B2
chr1    144124628   144128902   HFE2
chr1    150769175   150779181   CTSK
chr1    154245300   154248277   HAX1
chr1    155204686   155210803   GBA
chr1    156084810   156108997   LMNA

第二列和第三列分别是基因的起点和终点。我想要做的是检查第一个数据帧中的行是否适合第二个数据帧的范围,如果是,则将基因(第二个数据帧的第4列)添加到第一个数据帧。

我当前的实现使用嵌套for循环来检查第一个数据帧中的每个条目与第二个数据帧中的所有条目。是否有任何R功能可以帮助我完成这项任务?

简而言之:我需要检查第一个向量中一行中的值是否在不同大小的第二个向量中指定的范围内,然后从第二个向量中提取值。

4 个答案:

答案 0 :(得分:4)

使用dplyr

getValue <- function(x, data) {
  tmp <- data %>%
    filter(V2 <= x, x <= V3)
  return(tmp$V4)
}

x <- c(107599440, 150769180, 155204690)
sapply(x, getValue, data=df)

返回:

[1] "PRMT6" "CTSK"  "GBA" 

注意:我将您的数据复制到列名为dfV1V2V3的数据框V4中。列V2V3是范围的下限值和上限值。

df <- read.table(text="chr1    100088228   100162167   AGL
chr1    107599438   107600565   PRMT6
chr1    115215635   115238091   AMPD1
chr1    11850637    11863073    MTHFR
chr1    119958143   119965343   HSD3B2
chr1    144124628   144128902   HFE2
chr1    150769175   150779181   CTSK
chr1    154245300   154248277   HAX1
chr1    155204686   155210803   GBA
chr1    156084810   156108997   LMNA", stringsAsFactors=FALSE)

<强>更新

如果有多个匹配项,则会返回第一个匹配项:

getValue <- function(x, data) {
  tmp <- data %>%
    filter(V2 <= x, x <= V3) %>%
    filter(row_number() == 1)
  return(tmp$V4)
}

有多个排名功能。查看?row_number了解详情。

答案 1 :(得分:1)

你走了。这个答案取决于评论中讨论的假设,即范围既不重叠也不反对。

d <- read.table(text='chr1    100088228   100162167   AGL
chr1    107599438   107600565   PRMT6
chr1    115215635   115238091   AMPD1
chr1    11850637    11863073    MTHFR
chr1    119958143   119965343   HSD3B2
chr1    144124628   144128902   HFE2
chr1    150769175   150779181   CTSK
chr1    154245300   154248277   HAX1
chr1    155204686   155210803   GBA
chr1    156084810   156108997   LMNA')

# Since your original vector does not contain positions 
# that are in any of the ranges in your second data.frame, 
# I choose new values and commented the range they should belong to.
v <- read.table(text="
119958153 # HSD3B2
154245310 # HAX1
156084820 # LMNA")

# order the first data.frame by the ranges
d <- d[order(d[[2]]), ]

# create a vector breaks from the interval ranges
breaks <- as.vector(do.call(rbind, d[c(2,3)]))
ints <- ceiling(findInterval(v[[1]], breaks)/2)

v$AGL <- d[ints, 4]
#          V1    AGL
# 1 119958153 HSD3B2
# 2 154245310   HAX1
# 3 156084820   LMNA

答案 2 :(得分:0)

我意识到你要求一个功能,但这是一种不需要嵌套循环的方法,使用一些假数据。

x <- as.vector(c(1:3,6:9))      #Create a vector with values 1 to 3, and 6 to 9
y <- c(1:5)                     #Create a vector with values 1 to 5

inrange <- matrix(nrow=6,ncol=1)    #Create an empty matrix the same length as x
for (i in 1:nrow(x)){    
    inrange[i] <- ifelse((x[i] <= max(y) & x[i] >= min(y)),
        1,0)                      #This if statement evaluates each row of x to determine 
                }                 #whether the row is greater than/equal to the miniumum
                                  #or less than/equal to the maximum of y

&#34; INRANGE&#34;如果x的值在y的范围内,则现在取值为1;如果不是,则取值为0.

答案 3 :(得分:0)

假设v是你的向量,df是带有chr,start,stop,gene列的数据帧, 然后另一个简单的解决方案是

sapply(v, function(v.element) df[v.element >= df["start"] & v.element <= df["stop"],"gene"])