Я пытаюсь реализовать функцию для получения значений из одной таблицы на основе другой. Фактические данные имеют> 50 000 наблюдений, поэтому реализация этого вложенного цикла неэффективна. В последние несколько дней я пытаюсь найти SO, чтобы найти что-то, что работает, но не удалось. Мои данные не имеют особого порядка (отдельные лица, сегменты и т. Д.), Поэтому он должен работать, даже если все не в порядке.R - Вложенные для циклов и медленной производительности
Вот игрушечные примеры моих данных для работы с:
region_map <- data.frame(Start = c(721290, 1688193), End= c(1688192, 2926555))
individual <- c("Ind1","Ind2","Ind3","Ind4")
segment <- data.frame(SampleID = c("Ind1","Ind1","Ind2","Ind2","Ind3","Ind3","Ind4","Ind4","Ind4"),
Start = c(721290, 1688194, 721290, 1688200, 721290, 2926600, 721290, 1688193, 690),
End = c(1688192, 2926555,1688190, 2900000, 2926555, 3000000, 1500000, 2005000, 500000),
State = c(1,2,2,5,4,2,2,6,5))
И вот упрощенный пример того, что я пытаюсь сделать:
Generate.FullSegmentList <- function(segments, individuals, regionmap){
FullSegments <- data.frame()
for(region in 1:nrow(regionmap)){
for(ind in individuals){
# If there is not a segment within that region for that individual
if(nrow(
segments[segments$start >= regionmap$Start[region] &
segments$End <= regionmap$End[region] &
segments$SampleID == ind , ]
) == 0){
Temp <- data.frame(SampleID = ind,
Start = regionmap$Start[region],
End = regionmap$End[region],
State = 3
)
}
# If there is a segment within that region for that individual
if(nrow(
segments[segments$Start >= regionmap$Start[region] &
segments$End <= regionmap$End[region] &
segments$SampleID == ind , ]
) == 1){
Temp <- data.frame(SampleID = segments$SampleID,
Start = regionmap$Start[region],
End = regionmap$End[region],
State = segments$State[segments$Start >= regionmap$Start[region] &
segments$SampleID == ind ]
)
}
FullSegments <- list(FullSegments, Temp)
}
}
FullSegments
}
В словах, мне нужно посмотреть в каждой области (~ 53 000) и присвойте значение (State
, если оно не существует, укажите значение 3) в область для каждого individual
, а затем создайте новый data.frame с каждой областью для каждого человека. Чтобы сделать это, я просматриваю регионы, а затем люди, находя segment
(их насчитывается ~ 25 000), которые пересекаются с областью, а затем присоединяют ее к таблице.
Вот что вывод из приведенных выше данных игрушечных даст:
SampleID Start End State
Ind1 721290 1688192 1
Ind1 1688193 2926555 2
Ind2 721290 1688192 2
Ind2 1688193 2926555 5
Ind3 721290 1688192 4
Ind3 1688193 2926555 4
Ind4 721290 1688192 2
Ind4 1688193 2926555 6
Эта функция как есть работает точно, как мне это нужно, чтобы, за исключением того, что это займет очень много времени для запуска (с помощью system.time, я понял, что для запуска потребуется более 3 месяцев). Я знаю, что должен быть лучший способ сделать это. Я попытался реализовать функции приложения, и я видел в некоторых других вопросах использование списков вместо data.frame. Я также видел, что для упрощения этого существуют параметры data.table и plyr. Я пробовал их, но не добился успеха в работе с вложенным циклом с операторами if.
Я был бы признателен за объяснение любых полученных ответов, так как это первый раз, когда я написал все это сложное.
Вопросы Я думаю актуальны:
многие другие вопросы на вложенные в петлях вовлекают делать расчеты, которые хорошо работают для этого функцию применения (например apply(df, 1, function(x){ mean(x) }
) , но я не смог принять это значение для отображения значений из data.frame в data.frame.
Это работает для меня, и я могу понять и изменить его для своих реальных данных. В стороне, я должен был использовать пакет GenomicRanges для своих данных, потому что у меня также была информация о хромосоме. Мне потребовалось время, чтобы все понять, но спасибо за очень тщательные и полезные объяснения! –
О, и я использовал system.time времени: user: 0.46, system: 0.06, истек: 0.51. Довольно удивительно. –
@GaiusAugustus Похоже, у вас был продуктивный день; если ваши вопросы связаны с Bioconductor, лучше разместить их на [сайте поддержки Bioconductor] (https://support.bioconductor.org) –