我有一个类似的数据集
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
类型的循环可能会更好,但我不知道该怎么做。