有没有一种方法可以使用R中的apply函数之一来优化此循环?

时间:2020-06-24 01:46:01

标签: r loops apply

我在R中有以下两个数据帧:

> head(gene)

    V1        V2 V3
1 chr2 178525989 10
2 chr2 178525990 10
3 chr2 178525991 10
4 chr2 178525992 10
5 chr2 178525993 10
6 chr2 178525994 10

> head(exons)

    V1  V2          V3        V4        V5 V6 V7 V8  V9
1 chr2 lrg exonic_part 178807212 178807423  .  -  . 001
2 chr2 lrg exonic_part 178804552 178804655  .  -  . 002
3 chr2 lrg exonic_part 178802138 178802341  .  -  . 003
4 chr2 lrg exonic_part 178800395 178800682  .  -  . 004
5 chr2 lrg exonic_part 178799825 178799910  .  -  . 005
6 chr2 lrg exonic_part 178799487 178799731  .  -  . 006

exons$V4exons$V5中的每个对都表示范围的开始和结束。 exons中有364行,因此有364对。

我需要做的是遍历gene$V2的每个元素,并检查它是否包含在exons的这些范围中。如果包括在内,则需要在另一个向量中添加一个“外显子”条目,如果不包括在内,则需要在该向量中添加一个“内含子”条目。

因此,例如,如果gene$V2的前三个元素至少包含在一个范围内,而后三个则没有,那么我希望得到一个这样的向量:

> include_exclude[1:6]
[1] "exon" "exon" "exon" "intron" "intron" "intron"

目前,我正在使用inside.range()中的spatstat.utils函数,该函数将一个或多个要检查的值(x)和一个范围({{1} }),如果在范围内,则输出r,如果超出范围,则输出TRUE。我正在循环中使用它:

FALSE

但是,这显然是一种极其低效的解决方案。我怀疑使用R中的include_exclude <- c() for (i in 1:dim(gene)[1]){ list <- c() for (x in 1:dim(exons)) { list <- c(list,inside.range(as.numeric(gene$V2[i]),as.numeric(exons[x,4:5]))) } if (sum(list) > 0) {include_exclude <- c(include_exclude, "exon")} else {include_exclude <- c(include_exclude, "intron")} print(i) #to see how far along the loop is } 函数之一会有更有效的方法,但是我从来没有真正理解过它们,也不太想知道如何在此设置中使用它们。有人可以帮忙吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用V4V5Map列之间创建一个序列,并检查gene$V2中是否存在任何值并相应地分配值。

all_sequence <- unique(unlist(Map(`:`, exons$V4, exons$V5)))
gene$include_exclude <- ifelse(gene$V2 %in% all_sequence, 'exon', 'intron')

使用ifelse很容易理解,但是您也可以在没有ifelse的情况下执行此操作。

gene$include_exclude <- c('intron', 'exon')[(gene$V2 %in% all_sequence) + 1]

答案 1 :(得分:0)

如果您的每个gene$V2都在exons$V4$V5的至少一个范围内,则返回此值。

sapply(gene$V2, function(v) any(exons$V4 <= v & v <= exons$V5, na.rm = TRUE))
# [1] FALSE FALSE FALSE FALSE FALSE FALSE

很容易将其转换为"exon""intron"(使用ifelsedplyr::if_elsedata.table::fifelse或仅使用向量查找),如

rets <- sapply(gene$V2, function(v) any(exons$V4 <= v & v <= exons$V5, na.rm = TRUE))
ifelse(rets, "exon", "intron")
# [1] "intron" "intron" "intron" "intron" "intron" "intron"
c("intron", "exon")[ 1 + rets ]
# [1] "intron" "intron" "intron" "intron" "intron" "intron"