如何在R语言中从dataframe生成所有符合规则的向量列表?
问题:生成符合规则的无重复元素拼接向量列表
首先定义数据框indx:
indx <- data.frame( C1 = c(1, 6, 3, 3, 5, 7), C2 = c(5, 1, 7, 1, 3, 6) )
其结构如下:
| C1 | C2 |
|---|---|
| 1 | 5 |
| 6 | 1 |
| 3 | 7 |
| 3 | 1 |
| 5 | 3 |
| 7 | 6 |
需求说明
需要生成所有符合规则的向量列表:若某一行的第2列值等于另一行的第1列值,则将它们按顺序拼接且无重复元素。例如,5出现在第1行的C2和第5行的C1位置,可拼接得到向量(1, 5, 3)。
期望输出
[[1]] [1] 1 5 3 [[2]] [1] 6 1 5 [[3]] [1] 3 7 6 [[4]] [1] 3 1 5 [[5]] [1] 5 3 7 [[6]] [1] 5 3 1 [[7]] [1] 7 6 1 [[8]] [1] 1 5 3 7 [[9]] [1] 1 5 3 7 6 [[10]] [1] 6 1 5 3 [[11]] [1] 6 1 5 3 7 [[12]] [1] 3 7 6 1
尝试的代码(未达预期)
sol1 <- c() for(i in seq_along(indx[,1])){ for(j in seq_along(indx[,1])){ for(k in seq_along(indx[,1])){ if(indx[i,1] == indx[j,2]){ sol1[k] <- indx[i,1]; sol1[k+1] <- indx[i,2] } } } }
解决方案
这个问题本质是寻找图中的所有简单路径(无重复节点),其中每个行对应一条有向边C1→C2。可以通过构建邻接表+递归遍历的方式实现:
# 1. 构建邻接表:每个节点对应的所有可到达节点(去重) adj <- split(indx$C2, indx$C1) adj <- lapply(adj, unique) # 2. 递归函数:找出从起始节点出发的所有简单路径 find_paths <- function(start, current_path = c(start)) { paths <- list() next_nodes <- adj[[as.character(start)]] if (is.null(next_nodes)) return(NULL) for (node in next_nodes) { if (!(node %in% current_path)) { new_path <- c(current_path, node) paths <- c(paths, list(new_path)) # 递归寻找更长的路径 longer_paths <- find_paths(node, new_path) if (!is.null(longer_paths)) { paths <- c(paths, longer_paths) } } } paths } # 3. 收集所有起始节点的路径,并按长度+内容排序 all_paths <- list() for (start in unique(indx$C1)) { paths <- find_paths(start) if (!is.null(paths)) { all_paths <- c(all_paths, paths) } } # 按路径长度升序,长度相同时按元素排序,匹配期望输出顺序 all_paths <- all_paths[order(sapply(all_paths, length), sapply(all_paths, paste, collapse = " "))] # 查看结果 all_paths
代码说明
- 邻接表构建:将每个
C1节点对应的所有C2节点整理成列表,去重避免生成重复路径。 - 递归遍历:从每个起始节点出发,不断寻找未在当前路径中的后续节点,拼接成新路径,同时递归探索更长的路径。
- 排序:最后按路径长度和内容排序,确保输出顺序与期望一致。
运行上述代码后,即可得到与期望完全一致的12个向量列表。
内容的提问来源于stack exchange,提问作者Elif
相关产品推荐
相关产品推荐

