2016-07-25 4 views
1

У меня есть dataframe «DFA» (65000 строк) форма:Повторяющихся подмножеств и арифметика набора данных на основе второго dataframe

Chr Pos  NCP  NCP_Ratio 
1 72  1.06 0.599 
1 371  4.26 1.331 
1 633  2.10 2.442 
1 859  1.62 1.276 
1 1032 7.62 4.563 
1 1199 6.12 4.896 
1 1340 13.22 23.607 

Я желаю, чтобы использовать значение Chr и Pos в каждой строке dfA чтобы последовательно подмножество второго data.frame dfB формы:

Chr Pos Watson Crick 
1 1 5  0 
1 2 5  0 
1 4 1  0 
1 6 1  0 
1 7 1  0 
1 8 2  0 
1 9 2  0 
1 12 1  0 
1 14 1  0 
1 15 2  0 
1 22 1  0 

dfB имеет около 4 миллионов строк.

Каждый раз, когда я подмножество dfB, я хотел бы получить значения для интересующей области на основе диапазона в Pos (т.е. +/- 1000 значение Pos в dfA), и добавить их в третью данных .frame dfC, который изначально заполняется нулями.

У меня есть эта работа, пробирая каждый ряд dfA. Но из-за 65 000 строк требуется несколько часов. Итак, мои вопросы:

  1. Есть ли лучший/более эффективный способ?

  2. Какая часть моего кода замедляет это вниз так страшно «

Мой код:

temp=NULL 
width=300 # Region upstream and downstream of centrepoint # 
padding=50 # Add some padding area to table # 
width1=width+padding 
dfC=data.frame(NULL) 
dfC[1:((width1*2)+1),"Pos"]=(1:((width1*2)+1)) # Create Pos column # 

# Prefill dfC table with zeros # 
dfC[1:((width1*2)+1),"Watson"]=0 
dfC[1:((width1*2)+1),"Crick"]=0 

for (chrom in 1:16) { # LOOP1. Specify which chromosomes to process # 

    dfB.1=subset(dfB,Chr==chrom) # Make temp copy of the dataframes for each chromosome # 
    dfA.1=subset(dfA, Chr==chrom) 

for (i in 1:nrow(dfA.1)) { # LOOP2: For each row in dfA: 

    temp=subset(dfB.1, Pos>=(dfA.1[i,"Pos"]-width1) & Pos<=(dfA.1[i,"Pos"]+width1)) # Create temp matrix with hits in this region 
    temp$Pos=temp$Pos-dfA.1[i,"Pos"]+width1+1 
    dfC[temp$Pos,"Watson"]=dfC[temp$Pos,"Watson"]+temp[,"Watson"] 
    dfC[temp$Pos,"Crick"]=dfC[temp$Pos,"Crick"]+temp[,"Crick"] 

} # End of LOOP2 # 
} # End of LOOP1 # 

Пример вывода в следующем виде - где Pos содержит значения от 1 до? 2000 (представляя область от -1000 до +1000, фланкируя каждую центральную позицию Pos в dfA), а столбцы Watson/Crick содержат сумму хитов для каждого местоположения.

Pos Watson Crick 
1 15  34 
2 35  32 
3 11  26 
4 19  52 
5 10  23 
6 32  17 
7 21  6 
8 15  38 
9 17  68 
10 28  54 
11 27  35 
etc 
+0

Было бы полезно, если бы вы включили ожидаемый вывод для кода примера. Кроме того, рассмотрите размещение данных в форме 'dput' – Sumedh

+0

Спасибо за помощь в редактировании/форматировании. Я добавляю пример вывода. Я не знаком с dput, но сейчас я читаю помощь. – Matt

ответ

0

Я только очистил ваш код, поэтому не ожидайте большого улучшения, но я думаю, что эта версия может работать немного быстрее.

width <- 300 
padding <- 50 
width1 <- width + padding  
dfC <- data.frame(Pos=1:((width1*2)+1), Watson=0, Crick=0) 
for (chrom in 1:16) { 
    dfB1 <- subset(dfB, Chr == chrom) 
    for (pos in dfA$Pos[dfA$Chr == chrom]) { 
     dfB2 <- dfB1[(dfB1$Pos >= pos - width1) & (dfB1$Pos <= pos + width1), ] 
     rows <- dfB2$Pos - pos + width1 + 1 
     dfC$Watson[rows] <- dfC$Watson[rows] + dfB2$Watson 
     dfC$Crick[rows] <- dfC$Crick[rows] + dfB2$Crick 
    } 
} 
Смежные вопросы