【发布时间】:2020-07-17 04:25:30
【问题描述】:
我想为给定位置上方和下方的行创建一个新列,其中包含在不同列中给出的一系列值。让我们通过一个例子来更好地解决这个问题。
我的数据框如下所示:
library("tidyverse")
df <- tibble(POS = c("A","C","G","G","C","C","C","A","A","G","T","C","A"),
GET = c(FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE))
# A tibble: 13 x 2
POS GET
<chr> <lgl>
1 A FALSE
2 C FALSE
3 G FALSE
4 G FALSE
5 C TRUE
6 C FALSE
7 C FALSE
8 A FALSE
9 A FALSE
10 G FALSE
11 T FALSE
12 C TRUE
13 A FALSE
给定行号i 和窗口大小,我想连接POS 中的值以生成序列SEQ。例如,如果窗口扩展为 2(因为它在上方延伸两行,下方延伸两行),则第一次观察的 SEQ 值将只是“ACG”,但对于第三次观察,它将是“ACGGCC”。
但是,我只想做一些观察,那些带有GET==TRUE 的观察,所以理想的输出应该如下所示:
# A tibble: 2 x 3
POS GET SEQ
<chr> <lgl> <chr>
1 C TRUE GGCCC
2 C TRUE GTCA
无论如何,所有行的SEQ 值的解决方案也是有效的,我正在寻找的实际上不是问题本身的解决方案,而是一个有效的解决方案(见下文)。
我是怎么做的
这是我编写的代码:
window_extension <- 2
size <- window_extension * 2 + 1
for (i in 1:size) {
if (i <= window_extension) {
df <- df %>% dplyr::mutate(!!paste("SEQ", i, sep="") := dplyr::lag(POS, window_extension + 1 - i))
} else if (i > window_extension + 1) {
df <- df %>% dplyr::mutate(!!paste("SEQ", i, sep="") := dplyr::lead(POS, window_extension - (size-i)))
} else {
df <- df %>% dplyr::mutate(!!paste("SEQ", i, sep="") := POS)
}
}
df %>% tidyr::unite("SEQ", tidyselect::starts_with("S"), sep="", remove = TRUE, na.rm=TRUE) %>% dplyr::filter(GET)
此解决方案的问题在于,它会生成一个中间数据帧(循环之后的df),其中包含size 变量所指示的列数。所以你可以想象,如果size很大,内存的负担就会变大。这本身就是一个问题,特别是当只有几行是真正感兴趣的时候。浪费了太多内存。
希望会有一些专门的功能来实现这一点。我希望用 dplyr 滞后和领先来解决问题,但没有运气。有什么想法吗?
【问题讨论】:
-
嗨 elcortegano,这个示例 tibble 看起来很像 DNA 序列。也许您可以提供有关该问题的更多信息,因为您的问题之前可能已经解决。也许您有一个基因组位置列表,并且您想提取该位置周围不同大小的序列?
-
这实际上是一个 DNA 序列。目标是检索围绕某些感兴趣位置的序列。因此,如果窗口扩展如上所述为 2 bp,我们将获得 5 bp 区域,以该感兴趣位置为中心。
-
您如何确定
GET是否只是基因组位置?您是否使用参考基因组? BAM 文件? -
在我看来,问题中列出的方法不是最理想的。
bedtools或使用GenomicRanges包会好得多。 -
祝你好运。如果您需要更多帮助,您也可以考虑在bioinformatics.stackexchange.com 上提问。