Как эффективно объединить два кадра данных в R в один, пересчитав значение для каждой новой ячейки (предпочтительно с использованием dplyr) - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть таблица MySQL, которая содержит данные о некоторых анализах, которые я делаю.Это выглядит так: таблица MySQL

Вот также примерный набор данных, соответствующий этой таблице:

species  chrom  pos   strand  ratio   coverage  context  

X        Y      64    +       0.25    12        TACGT  

X        Y      65    -       0.5     20        ACGTT

X        Y      107   +       0.8     10        CCCGT  

X        Y      108   -       0.4     30        CCGTG

Как вы можете видеть, у меня в настоящее время есть таблица с7 полей.То, что я хочу сделать, это объединить все ячейки для «плюс» цепи с ячейками следующей «-» цепи.Затем я получу новую таблицу, которая содержит 6 полей (все, кроме поля прядей) и половину строк старой таблицы.Однако мне нужно пересчитать содержимое каждой ячейки в моей новой таблице на основе информации старой таблицы, содержащей информацию о цепях.

Таким образом, поля «разновидности» и «хром» содержат идентичную информацию для каждойячеек, которые будут объединены.Мне просто нужно сохранить один из двух.Для поля pos я могу хранить только информацию из цепочки "+".То же самое для поля "контекст".Однако для полей «охват» и «коэффициент» мне нужно выполнить расчеты.Поле «покрытие» будет содержать ячейки, которые будут суммой ячеек покрытия «+» и «-».Поле «коэффициент» будет рассчитываться с использованием следующей функции:

new_ratio = («коэффициент +» * «охват +» + «коэффициент-» * «охват») / «охват +» + «охват -»

Так что это будет функцией старых соотношений и покрытий.

Новая таблица должна выглядеть следующим образом:

species  chrom  pos  ratio       coverage  context  

X        Y      64   0.40625     32        TACGT  

X        Y      107  0.5         40        CCCGT

Я успешно написал сценарий, который может создатьновая таблица в точности так, как я хочу, но она требует НАВСЕГДА (я делаю это в R)!

То, что я делаю, - это то, что я разделяю таблицу на два кадра данных, плюс-кадр данных и"минус" датафрейм.Затем я воссоздаю новую таблицу строка за строкой, выполняя вычисления, которые я описал выше.

Этот код действительно неэффективен, поскольку воссоздание новой таблицы занимает слишком много времени.У меня есть десятки миллионов записей в моей исходной таблице (:

Есть ли способ сделать это более эффективно, может быть, сочетая сразу созданные «плюс» и «минус» кадры данных, которые я создал, без необходимостиделать этот ряд за строкой?

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 14 ноября 2018
# read in data
dat <- structure(list(species = c("X", "X", "X", "X"), chrom = c("Y", 
"Y", "Y", "Y"), pos = c(64L, 65L, 107L, 108L), strand = c("+", 
"-", "+", "-"), ratio = c(0.25, 0.5, 0.8, 0.4), coverage = c(12L, 
20L, 10L, 30L), context = c("TACGT", "ACGTT", "CCCGT", "CCGTG"
)), class = "data.frame", row.names = c(NA, -4L))

Вы можете разбить данные на две части в соответствии с состоянием цепей и объединить два фрейма данных по видам и хрому

dat[dat$strand == '+',] -> plus_strand
dat[dat$strand == '-',] -> minus_strand
merge(plus_strand, minus_strand, by=c('species','chrom')) -> newdat
# filter out lines where the difference between pos = 1    
newdat[newdat$pos.x - newdat$pos.y == -1,] -> newdat

Объединенные данные выглядят следующим образом:

> newdat
  species chrom pos.x strand.x ratio.x coverage.x context.x pos.y strand.y ratio.y coverage.y context.y
1       X     Y    64        +    0.25         12     TACGT    65        -     0.5         20     ACGTT
4       X     Y   107        +    0.80         10     CCCGT   108        -     0.4         30     CCGTG

Я не знаю, как вернуть числа, которые вы выложили выше, но, похоже, это вернет правильное количество строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...