R中列表中的匹配元素
Matching elements within list in R
假设我有一个列表,定义如下:
test <- list(1:4,5,8,1,2:3,10)
我想以某种方式匹配列表中包含任何相似数字的元素。例如,我想匹配 test[[1]]
和 test[[4]]
,因为它们都包含 1。同样,test[[1]]
和 test[[5]]
也会匹配,因为它们都包含 2 和 3。
匹配后,我想为每个匹配构造一个唯一的id。例如,答案将是以下列表
ans <- list(1,2,3,1,1,4)
编辑:
这个答案背后的直觉是,如果列表 test
的元素共享一个公共匹配项,它们将获得相同的 ID。这意味着即使 test[[4]]
和 test[[5]]
不匹配,但它们都匹配 test[[1]]
的事实意味着它们将被分配相同的 id。
这显然是一个玩具示例。在实践中,我想将此匹配应用于一个大列表(>100,000k 元素)。考虑到这一点,算法需要有一定的效率。
提前致谢!
这可能是一个低效的答案,因为它嵌套了 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
我还建议 运行 在更大的测试样本或部分真实数据上进行此操作,因为示例非常小,我可能会漏掉一些东西。
这是使用 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
假设我有一个列表,定义如下:
test <- list(1:4,5,8,1,2:3,10)
我想以某种方式匹配列表中包含任何相似数字的元素。例如,我想匹配 test[[1]]
和 test[[4]]
,因为它们都包含 1。同样,test[[1]]
和 test[[5]]
也会匹配,因为它们都包含 2 和 3。
匹配后,我想为每个匹配构造一个唯一的id。例如,答案将是以下列表
ans <- list(1,2,3,1,1,4)
编辑:
这个答案背后的直觉是,如果列表 test
的元素共享一个公共匹配项,它们将获得相同的 ID。这意味着即使 test[[4]]
和 test[[5]]
不匹配,但它们都匹配 test[[1]]
的事实意味着它们将被分配相同的 id。
这显然是一个玩具示例。在实践中,我想将此匹配应用于一个大列表(>100,000k 元素)。考虑到这一点,算法需要有一定的效率。
提前致谢!
这可能是一个低效的答案,因为它嵌套了 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
我还建议 运行 在更大的测试样本或部分真实数据上进行此操作,因为示例非常小,我可能会漏掉一些东西。
这是使用 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