У меня есть набор данных, например
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
тип циклов будет лучше, но я не могу понять, как это сделать.