我有一个data.table,其中有两列“From”和“To”,如下所示:
data.table(From = c(1,1,1,1,2,2,2,2,3,3,3,4,4,5),
To = c(3,4,5,6,3,4,5,6,4,5,6,5,6,6))
data.table将始终按上例所示排序,其中“From”和“To”值从最小到最大递增。
我需要找到一个从第一个“From”(始终为“1”)开始到最后一个“To”值的“路径”,但始终选择最小的“To”值。在上面的例子中,我将有1 --〉3,然后3 --〉4,然后4 --〉5,最后5 --〉6。
然后我想返回一个向量1,3,4,5和6,代表链接的值。
我能想到的唯一方法是使用while或for循环,循环遍历每组“From”值,并迭代选择最小值。这似乎效率很低,而且在我的实际数据集上可能会非常慢,因为它超过100,000行。
有没有类似于数据表的解决方案?我也认为igraph可能会有一个方法,但我必须承认,我目前对这个函数几乎一无所知。
如有任何帮助,我们将不胜感激。
谢谢你,菲尔
编辑:
感谢到目前为止所有的回答。我的例子/解释不是很好,抱歉,因为我没有解释'From' / 'To'对不需要一直到'To'列的结束值。
使用以下注解中的示例:
dt <- data.table(From = c(1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 5),
To = c(3, 4, 5, 6, 3, 4, 5, 6, 5, 6, 6))
输出将简单地是c(1,3)的向量,因为它将从1开始,选择最小值3,然后因为没有“从”值"3“,它将不再继续。
再举一个例子:
dt <- data.table(From = c(1,1,1,2,2,3,3,4,4),
To = c(2,3,4,5,6,4,7,8,9))
这里的预期输出是向量c(1,2,5);遵循路径1 --〉2,然后2 --〉5,在该点停止,因为在“From”列中没有“5”值。
希望这是有意义的,并为最初的问题缺乏明确性表示歉意。
谢谢你,菲尔
5条答案
按热度按时间aemubtdh1#
您可以尝试以下代码
或者使用
subcomponent
更简单(如@clp)其给出了
u3r8eeie2#
假设有一个有序的 From 和 To 列表,这可能有效。
它首先按 From 分组,按 To 压缩,然后使用
shift
排除不匹配的 From-To 值。如果缺少跳转(例如,To 3但 From 3缺失),则打印
NULL
jq6vz3qz3#
从
Igraph
和subcomponents()
使用。在ThomasisCoding的评论之后,我意识到
graph_from_data_frame
是通过名称创建图的。如果图很大(1E6),这是对内存(和时间)的浪费。还要注意graph_from_edgelist(as.matrix(...))
要快得多。第一次尝试
gtlvzcf84#
我似乎无法得到其他答案来处理某些表。例如,
这个
igraph
解决方案似乎是基于更广泛的测试而工作的:ycl3bljg5#
一个连续的解决方案是可行的。复制一百万行 Dataframe 在我的系统上花了8秒。
输出。
更新后,菲尔的最后一次编辑。第一步是简化输入(df)。
将路径设置为第一个开始节点,然后追加结束节点
输出量: