猿问

将 JavaScript 异步和 igraph 代码移植到 R?

我正在努力将一些 JavaScript 代码(包括异步和图形功能)移植到 R。请帮助!


这是我尝试移植的内容:


import jsonpFetch from "./jsonpFetch";

import bus from '../bus';


/**

 * This function builds a graph from google's auto-suggestions.

 */

export default function buildGraph(entryWord, pattern, MAX_DEPTH, progress) {

  entryWord = entryWord && entryWord.trim();

  if (!entryWord) return;


  entryWord = entryWord.toLocaleLowerCase();


  const insertPosition = pattern.indexOf('...');

  if (insertPosition < 0) {

    throw new Error('Query pattern is missing "..."');

  }

  const queryPosition = pattern.indexOf('[query]');

  if (queryPosition < 0) {

    throw new Error('Query pattern is missing "[query]" keyword');

  }


  if (insertPosition < queryPosition) {

    throw new Error('[query] should come before ...');

  }


  let cancelled = false;

  let pendingResponse;

  let graph = require('ngraph.graph')();

  graph.maxDepth = MAX_DEPTH;

  let queue = [];

  let requestDelay = 300 + Math.random() * 100;

  progress.startDownload();


  startQueryConstruction();


  return {

    dispose,

    graph

  }


  function dispose() {

    cancelled = true;

    if (pendingResponse) {

      pendingResponse.cancel();

      pendingResponse = null;

    }

  }


  function startQueryConstruction() {

    graph.addNode(entryWord, {depth: 0});

    fetchNext(entryWord);

  }


  function loadSiblings(parent, results) {

    let q = fullQuery(parent).toLocaleLowerCase();

    var parentNode = graph.getNode(parent);


    if (!parentNode) {

      throw new Error('Parent is missing for ' + parent);

    }


   

请注意,我已经包含了一些注释掉的 JavaScript 代码行,我不确定 R 的等价物是什么。对我来说,大部分晦涩的代码都集中在如何igraph在 R 中执行操作以及如何在 R 中异步执行操作(使用promises和/或futures)。

归属:https : //github.com/anvaka/vs/blob/master/src/lib/buildGraph.js

提前致谢!


慕森王
浏览 189回答 1
1回答

30秒到达战场

我最近一直在玩 igraph 和 API,所以这是相当新鲜的。我认为下面的代码可以满足您的需求,但它确实省略了一些复杂性(例如不会使 API 超时)。它不是非常快 - 我怀疑其中很多与使用 as_data_frame 接口来跟踪顶点有关。所以我确信它可以被优化并且我确信在某个时候 API 会以一种破坏它的编码返回一些东西,但这是一个开始。library(igraph)api_fetch <- function(query){&nbsp; &nbsp; result <- jsonlite::fromJSON(paste0('http://suggestqueries.google.com/complete/search?client=firefox&q=', httpuv::encodeURIComponent(query)))&nbsp; &nbsp; return(result)}build_query_graph <- function(entry_word, max_depth=2){&nbsp; &nbsp; # Create an empty graph&nbsp; &nbsp; graph <- make_empty_graph()&nbsp; &nbsp; entry_word <- tolower(trimws(entry_word))&nbsp; &nbsp; graph <- add_vertices(graph, 1, name=entry_word, searched=FALSE)&nbsp; &nbsp; # Keep on doing this until the graph hits the maximum depth from the entry word&nbsp; &nbsp; while(TRUE){&nbsp; &nbsp; &nbsp; &nbsp; # Look up the current vertices and find their depths from the entry word&nbsp; &nbsp; &nbsp; &nbsp; vertices <- as_data_frame(graph, what='vertices')&nbsp; &nbsp; &nbsp; &nbsp; vertex_depth <- distances(graph, v=entry_word)&nbsp; &nbsp; &nbsp; &nbsp; vertices$depth <- vertex_depth[match(colnames(vertex_depth), vertices$name)]&nbsp; &nbsp; &nbsp; &nbsp; # Find vertices at least one step from the maximum depth and that haven't&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; # already been searched and sort to get the shallowest at the top&nbsp; &nbsp; &nbsp; &nbsp; live_vertices <- subset(vertices, depth <= (max_depth - 1) & ! searched)&nbsp; &nbsp; &nbsp; &nbsp; live_vertices <- live_vertices[order(live_vertices$depth),]&nbsp; &nbsp; &nbsp; &nbsp; # If there are any vertices meeting these criteria, then query the API&nbsp; &nbsp; &nbsp; &nbsp; # otherwise bail from the while loop&nbsp; &nbsp; &nbsp; &nbsp; if(nrow(live_vertices)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Get the vertex name and query it&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this_vertex <- live_vertices$name[1]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res <- api_fetch(this_vertex)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # For each of the daughter results, check it isn't already a vertex&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # and add an edge from it to this_vertex&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(daughter in res[[2]]){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(! daughter %in% get.vertex.attribute(graph, 'name')){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- add_vertices(graph, 1, name=daughter, searched=FALSE)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- add_edges(graph, c(this_vertex, daughter))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Don't search this vertex again&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- set_vertex_attr(graph, 'searched', this_vertex, TRUE)&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; return(graph)}运行:> g <- build_query_graph('amazon')> gIGRAPH 0ec19b6 DN-- 90 100 --&nbsp;+ attr: name (v/c), searched (v/l)+ edges from 0ec19b6 (vertex names):&nbsp;[1] amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon prime&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon prime video&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[4] amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon uk&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon music&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon smile&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[7] amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon india&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon jobs&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon video&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[10] amazon&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->amazon customer service&nbsp; &nbsp; &nbsp; &nbsp;amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime video&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[13] amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime movies&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime music&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime now&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[16] amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime login&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime uk&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime tv&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[19] amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime cost&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;amazon prime&nbsp; &nbsp; &nbsp; ->amazon prime student&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amazon prime video->amazon prime video&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[22] amazon prime video->amazon prime video login&nbsp; &nbsp; &nbsp; amazon prime video->amazon prime video app&nbsp; &nbsp; &nbsp; &nbsp; amazon prime video->amazon prime video uk&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;+ ... omitted several edges> plot(g)考虑一下,重复重新计算所有距离并进行大量排序和匹配。在创建单个顶点时保存它们的深度可能会更快:build_query_graph <- function(entry_word, max_depth=2){&nbsp; &nbsp; # Create an empty graph&nbsp; &nbsp; graph <- make_empty_graph()&nbsp; &nbsp; entry_word <- tolower(trimws(entry_word))&nbsp; &nbsp; graph <- add_vertices(graph, 1, name=entry_word, depth=0, searched=FALSE)&nbsp; &nbsp; # Keep on doing this until the graph hits the maximum depth from the entry word&nbsp; &nbsp; while(TRUE){&nbsp; &nbsp; &nbsp; &nbsp; # Look up the current vertices and find their depths from the entry word&nbsp; &nbsp; &nbsp; &nbsp; vertices <- as_data_frame(graph, what='vertices')&nbsp; &nbsp; &nbsp; &nbsp; # Find vertices at least one step from the maximum depth and that haven't&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; # already been searched and sort to get the shallowest at the top&nbsp; &nbsp; &nbsp; &nbsp; live_vertices <- subset(vertices, depth <= (max_depth - 1) & ! searched)&nbsp; &nbsp; &nbsp; &nbsp; live_vertices <- live_vertices[order(live_vertices$depth),]&nbsp; &nbsp; &nbsp; &nbsp; # If there are any vertices meeting these criteria, then query the API&nbsp; &nbsp; &nbsp; &nbsp; # otherwise bail from the while loop&nbsp; &nbsp; &nbsp; &nbsp; if(nrow(live_vertices)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Get the vertex name and query it&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this_vertex <- live_vertices$name[1]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res <- api_fetch(this_vertex)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # For each of the daughter results, check it isn't already a vertex&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # add an edge from it to this_vertex and store the depth from the entry word&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(daughter in res[[2]]){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(! daughter %in% get.vertex.attribute(graph, 'name')){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- add_vertices(graph, 1, name=daughter, depth=NA, searched=FALSE)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- add_edges(graph, c(this_vertex, daughter))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- set_vertex_attr(graph, 'depth', daughter,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;distances(graph, v=entry_word, to=daughter))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Don't search this vertex again&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graph <- set_vertex_attr(graph, 'searched', this_vertex, TRUE)&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; return(graph)}
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答