我在R中有以下简单的data.frame:
structure(list(start = c(1L, 2L, 2L, 3L), end = c(2L, 10L, 3L,
4L), type = c("indirect", "indirect", "indirect", "direct")), .Names= c("start",
"end", "type"), row.names = c(NA, 4L), class = "data.frame")
表格视图如下:
start end type
1 1 2 indirect
2 2 10 indirect
3 2 3 indirect
4 3 4 direct
该表是网络的示例。每行显示从起点到终点的方向,例如,第一行描述来自" 1"的路径。至" 2"。
列"类型"只有通过以下附加信息才有意义:在这个例子中,我们正在寻找属于预定义" main"的每一个(子)路径。路径。在示例中,预定义的查询是"为了从起点1 到端点4 ,为我提供我需要的每个子路径。所有中间步骤都标记为"间接",只有以预定义结束节点结束的最后一步标记为"直接"。
现在的任务是过滤这些所有相关步骤(子路径)。在我们的示例中,只有以下路径为您带来1到4:
1 - > 2 - > 3 - > 4
然而,还有一个死胡同"路径:
1 - > 2 - > 10 - >死胡同(没有到4的连接路径)
现在的目标是过滤数据集,以便仅保留构成成功整体路径的一部分的行(=子路径),从1到4.因此,在当前示例中,我们希望保留除第2行之外的所有内容结果应如下所示:
start end type
1 1 2间接 2 2 3间接 3 3 4直接
这样做的简单方法是什么?请记住,在一个更复杂的场景中,我们必须以递归方式执行此操作,即,我可以使用更多"中间"起始节点和结束节点之间的步骤。 提前致谢!
更新:评论:不幸的是,我们不能使用像dplyr或data.table这样的库;使用基础R的解决方案将受到高度赞赏。
答案 0 :(得分:0)
这是我们所拥有的(我略微扩展的例子):
require(data.table)
target <- c(1,2,3,4,5)
dt <- data.table(start = c(1,2,2,3,2),
end = c(2,10,3,5,5),
type = c("indirect", "indirect", "indirect", "direct", "direct"))
df <- data.frame(start = c(1,2,2,3,2),
end = c(2,10,3,5,5),
type = c("indirect", "indirect", "indirect", "direct", "direct"))
分解为两步:
查找属于最终解决方案的子路径
dt[,overlap:=apply(dt[,.(start, end)], 1, function(x) all(x[1]:x[2] %in% target))]
df$overlap <- apply(df[,c("start", "end")], 1, function(x) all(x[1]:x[2] %in% target))
确定子路径是否与总目标路径相加
coverage <- NULL
#dt
all(unique(as.vector(unlist(apply(dt[overlap == TRUE,.(start, end)], 1, function(x) coverage <- c(coverage, x[1]:x[2]))))) %in% target)
#df
all(unique(as.vector(unlist(apply(df[df$overlap == TRUE,c("start", "end")], 1, function(x) coverage <- c(coverage, x[1]:x[2]))))) %in% target)
输出:
target
[1] 1 2 3 4 5
dt[overlap == TRUE]
df[df$overlap == TRUE,]
start end type overlap
1: 1 2 indirect TRUE
2: 2 3 indirect TRUE
3: 3 5 direct TRUE
4: 2 5 direct TRUE