满足条件时改进嵌套的for / while循环以合并行

时间:2019-03-20 14:33:20

标签: r loops for-loop while-loop apply

我有一个类似的数据集

df1 <- data.frame(IDs = c("id11", "id2", "id31", "id4", "id8"),
                  STRs = c("AA;AB;XDD;QWE;EE;RTEY;OPOP;TTTYTY", "XDD;EWE;TY;MN;WW", "QWE;EE;RTEY;AA", "XDD;OQW;TTTYTY", "XDD"),
                  cSTRs = c(8, 5, 4, 3, 1))

在第一列中有唯一的ID,在第二列中,对于每个ID,都有一组用分号分隔的字符串,在最后一列中是第2列中的字符串数。 我的任务是在ID的一组字符串相同或一组完全包含在另一组中时组合ID。

在组合ID时,我需要确保具有较高数字字符串的ID始终位于第一个位置,并且如果一个ID的字符串集包含在2个或多个其他ID中,则也应将其组合其ID总体上具有较高的字符串数。 因此,我首先需要在cSTR上对我的df进行排序(这里没有必要,因为数据已经排序了),然后可以进行如下嵌套的for / while循环

#making vectors
IDs <- as.vector(df1[[1]])
STRs <- as.vector(df1[[2]])
cSTRs <- as.vector(df1[[3]])

for(j in 1:length(IDs)){
  i <- j + 1

  while (i <= length(IDs)) {
    if(all(unlist(strsplit(as.character(STRs[i]), split = ";")) %in% unlist(strsplit(as.character(STRs[j]), split = ";")))){

      IDs[j] <- paste0(IDs[j], ";", IDs[i]) #combining IDS
      cSTRs[j] <- paste0(cSTRs[j], ";", cSTRs[i]) #combining counts

      #removing the values combined to the ID above
      IDs <- IDs[-i]
      STRs <- STRs[-i]
      cSTRs <- cSTRs[-i]

      i <- j + 1
    }else{
      i <- i + 1
    }
  }  
}

df2 <- data.frame(IDs = IDs, STRs = STRs, cSTRs = cSTRs)

给出

> df2
            IDs                              STRs cSTRs
1 id11;id31;id8 AA;AB;XDD;QWE;EE;RTEY;OPOP;TTTYTY 8;4;1
2           id2                  XDD;EWE;TY;MN;WW     5
3           id4                    XDD;OQW;TTTYTY     3

可以看到,id8虽然包含在id11 / id2和id4中,但它与id11 / id2组合在一起,因为它具有较高的字符串集。

代码有效,但是在处理5k行时已经很慢了。 我可以将while替换为经典的for循环,但这可能会稍作改进。 在这里,apply类型的循环可能会更好,但我不知道该怎么做。

0 个答案:

没有答案