簡體   English   中英

R-矢量化嵌套循環?

[英]R - Vectorising nested for loops?

我有兩個較大的數據框(如下所示的head(CON_FRA)和head(indels)),我想比較和修改它們的值。 我來自python背景,因此創建了此嵌套的for循環,實現了我的目標:找到indels $ V4的值(介於CON_FRAs $ V4和CON_FRAs $ V5之間),並向indels $ CON和CON_FRAs $ V6添加1緩慢(運行時間為1小時)。

誰能幫我向量化此代碼?

從側面講,我還意識到我不應該要求在嵌套循環中兩次聲明相同的if條件,但是在R中進行編程時,我發現很多事情是不直觀的,並且不能使R僅接受一個if語句中的2個動作。

CON_FRAs

V1        V2        V3        V4        V5 V6
1  1  57859401  58018691  57859401  58018691  0
2  1  97522550  97892513  97522550  97892513  0
3  1 214173802 224638502 214173802 224638502  0
4  1 184035608 184239812 184035608 184239812  0
5  2 140988941 141140259 390239564 390390882  0
6  2 169205756 170181166 418456379 419431789  0

插入和缺失

V1        V2        V3         V4         V5  V6     V7  V8            V9 V10 mut_type CON BIG FUN MRA LET recomb
1  6  96651182  96651183 57859401 57859402  AA      T CLL 001-0002-03TD  NA  COMPLEX   0   0   0   0   0      0
2 10  38406960  38406961 1718780121 1718780122  AG      - CLL 003-0005-09TD  NA      DEL   0   0   0   0   0      0
3  2  87017743  87017744  336268366  336268367   C     CT CLL 003-0005-09TD  NA  COMPLEX   0   0   0   0   0      0
4 20   5538748   5538750 2724112091 2724112093 CCC      A CLL    012-02-1TD  NA  COMPLEX   0   0   0   0   0      0
5  9 139390648 139390649 1678550376 1678550377  AG      - CLL    012-02-1TD  NA      DEL   0   0   0   0   0      0
6 10  10498176  10498180 1690871337 1690871341   - GAAAAA CLL           125  NA      INS   0   0   0   0   0      0

我的嵌套循環

for(j in 1:length(indels$V4)){
   for(i in 1:length(CON_FRAs$V4)){
     if(CON_FRAs$V4[i] < indels$V4[j] & indels$V4[j] < CON_FRAs$V5[i])
       indels$CON[j] = 1
     if(CON_FRAs$V4[i] < indels$V4[j] & indels$V4[j] < CON_FRAs$V5[i])
       CON_FRAs$V6[i] = CON_FRAs$V6[i] + 1}}

更新:我已經設法通過在單個循環中放置矢量化命令的一半方法來改善性能,從而消除了嵌套循環的指數增長,但是仍然需要兩個循環(請參見下文)。 這將運行時間減少到2分鍾以內。 現在這必須要做,因為它足夠快,如果有人可以提供完全矢量化的解決方案,它仍然會很感興趣

for(j in 1:length(indels$V4)){
  inc(CON_FRAs$V6[CON_FRAs$V4 < indels$V4[j] & indels$V4[j] < CON_FRAs$V5]) <- 1}

for(i in 1:length(CON_FRAs$V6)){
  indels$CON[CON_FRAs$V4[i] < indels$V4 & indels$V4 < CON_FRAs$V5[i]] <- 1}

至於您的旁注問題,這應該可以解決:

for(j in 1:length(indels$V4)){
   for(i in 1:length(CON_FRAs$V4)){
     if(CON_FRAs$V4[i] < indels$V4[j] & indels$V4[j] < CON_FRAs$V5[i]) {
       indels$CON[j] = 1
       CON_FRAs$V6[i] = CON_FRAs$V6[i] + 1}
                                 } }

從“矢量化”的角度考慮時,我想這實際上是兩個不同的問題,其中可能使用“外部”為邏輯測試生成矩陣。 它將借給在“ i”值內“ V6”值的累加完成的colSums,但對於“ indel $ CON”列,我認為這可能是“ any”的結果(使用來自a的applycolMax非基本包)在“ j”行上:

outer(1:nrow(indels), 
      1:nrow(CON_FRAs),
       function(X,Y) {CON_FRAs$V4[X] < indels$V4[Y] & 
                      indels$V4[Y] < CON_FRAs$V5[X]} )

      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,] FALSE FALSE FALSE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE FALSE
[3,] FALSE FALSE FALSE FALSE FALSE FALSE
[4,] FALSE FALSE FALSE FALSE FALSE FALSE
[5,] FALSE FALSE FALSE FALSE FALSE FALSE
[6,] FALSE FALSE FALSE FALSE FALSE FALSE

警告。 在較早的嘗試中,我得到了不同的結果。 固定邏輯表達式中的索引可以為我提供與代碼相同的(瑣碎的)結果,但是也許如果您放置一個更好的測試用例,我們可以更好地比較結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM