library(tidyverse) # for all the tidyverse goodies
library(reshape2) # For the melt function
Поскольку вы не предоставили воспроизводимый пример, я позволил себе создать свой собственный игрушечный фрейм данных, как показано ниже. Он имеет только 2 хромосомы, но этот метод должен быть применим к произвольному количеству хромосом и генов.
sorted_coords <- tibble(start_position = abs(rnorm(10)*10),
end_position = abs(rnorm(10)*10),
chromosome_name = c(rep(1,5),rep(2,5)))
Редактировать: ОП уточнил, что они хотели найти расстояние только до гена, а не до любого другого гена. Метод для выполнения последней части находится внизу, потому что я нашел это интересным. Новое решение здесь:
sorted_coords %>%
group_by(chromosome_name) %>%
arrange(chromosome_name, start_position) %>%
mutate(distance = start_position - lag(end_position, n = 1, default = 0))
Мы группируем по хромосомам, чтобы не делать ошибочных расчетов между хромосомами.
В конце сортируем по названию хромосомы для сортировки. Мы организуем по стартовой позиции, чтобы гены были в правильном порядке.
Мы рассчитываем расстояние как предложено. Начальная позиция текущей строки - конечная позиция предыдущей строки. Мы указываем (хотя это по умолчанию), что мы смотрим на строку раньше, и что если нет строки до того, как значение конечной позиции по умолчанию равно 0.
Старый ответ
Если вы хотите сравнить каждый ген с каждым другим геном, самый быстрый способ сделать это - создать матрицу. Как вы указали, мы хотим вычесть начало гена 1 до конца гена 2. Мне это не кажется правильным, но прошло уже много времени с тех пор, как я сделал биохимию :). Поскольку вам нужен один список пар, мы можем свернуть его (функция плавления).
Код ниже немного неясен для понимания, поэтому давайте разберем его.
sorted_coords %>%
group_by(chromosome_name) %>%
do( outer(.$start_position, .$end_position) %>%
melt() %>%
setNames(c("rows", "columns", "distance")))
- Мы берем наш фрейм данных и группируем его по каждой хромосоме, как вам нужно.
- Команда do позволяет нам выполнять сложные операции. Команда group_by гарантирует, что все, что мы делаем, по существу является изолированным для каждой хромосомы.
- Внешняя функция создает нашу матрицу для нас.
.
- это передаваемый нами фрейм данных (подмножество определенной хромосомы). Мы передаем два столбца, для которых нам нужно найти разницу.
- Функция melt превращает матрицу в фрейм данных для нас, указывая, какие два гена она использовала для вычисления разницы. Они численно перечислены, и вы можете вернуться и сравнить его. Я бы предложил использовать порядок, чтобы установить порядок, чтобы вы могли легко ссылаться на него.
- setNames просто устанавливает имена столбцов на что-то более разрешимое.
Это должно быть намного быстрее, чем запуск цикла for для всех ваших процессов. Если вы предоставите больше информации, я, скорее всего, уточню ответ.