想象一下,我有一个列表,定义如下:
test <- list(1:4,5,8,1,2:3,10)
如果它们包含任何类似的数字,我想以某种方式匹配列表的元素。例如,我想匹配test[[1]]
和test[[4]]
,因为它们都包含1.同样,test[[1]]
和test[[5]]
也会匹配,因为它们都包含2和3。 / p>
匹配后,我想构建一个对应每个匹配的唯一ID。例如,答案将是以下列表
ans <- list(1,2,3,1,1,4)
编辑:
这个答案背后的直觉是,如果列表test
的元素共享一个共同的匹配,它们会收到相同的ID。这意味着,即使test[[4]]
和test[[5]]
不匹配,但每个匹配test[[1]]
的事实意味着它们将被分配相同的ID。
这显然是一个玩具的例子。在实践中,我想将此匹配应用于大型列表(&gt; 100,000k元素)。考虑到这一点,算法需要有点效率。
提前致谢!
答案 0 :(得分:0)
这可能是一个非常有效的答案,因为它嵌套了for
和两个if
。它确实有用,所以它可能是你或其他人的起点。
test <- list(1:4,5,8,1,2:3,10)
ids <- 1
for (i in 2:length(test)) { # start at second because next loop is backwards
for (j in (i-1):1) { # will match against previous items
if (any(test[[j]] %in% test[[i]])) { # checks if there's any match between list items
ids <- c(ids, ids[j]) # repeat the matched id
break # leaves the loop if a match is found
}
}
if (length(ids) < i) { # if didn't match before
ids <- c(ids, max(ids) + 1) # creates a new id from the last
}
}
ids
# [1] 1 2 3 1 1 4
我还建议在更大的测试样本或部分实际数据上运行此操作,因为该示例非常小,我可能错过了一些内容。
答案 1 :(得分:0)
这是使用data.table
的一种方式:
require(data.table)
# generate a data.table from your data
id = rep(seq_along(test), sapply(test, length))
dt = data.table(id, val = unlist(test))
# solution
dt[, ans := id[1L], by=val][, ans := .GRP, by=ans][, ans[1L], by=id]$V1
# [1] 1 2 3 1 1 4