Улучшение вложенного цикла for / while для объединения строк при соблюдении критериев - PullRequest
0 голосов
/ 20 марта 2019

У меня есть набор данных, например

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))

В первом столбце есть уникальные идентификаторы, во втором столбце для каждого идентификатора есть набор строк, разделенных точкой с запятой, а в последнем столбцеколичество строк в столбце 2. Моя задача - объединить идентификаторы, если их набор строк идентичен или один набор полностью содержится в другом.

При объединении идентификаторов мне нужно убедиться, что идентификаторс более высоким номером строка всегда находится на первой позиции, также, если у идентификатора есть набор строк, содержащийся в 2 или более других идентификаторах, это должно быть объединено с идентификатором, который в целом имеет большее количество строк.Итак, сначала нужно отсортировать df по cSTR (здесь не обязательно, поскольку данные уже отсортированы), затем я мог бы сделать вложенный цикл 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 тип циклов будет лучше, но я не могу понять, как это сделать.

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