使用R过滤数据集中的直接路径

时间:2017-03-15 09:09:31

标签: r recursion

我在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的解决方案将受到高度赞赏。

1 个答案:

答案 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