Skip to content
This repository has been archived by the owner on May 23, 2019. It is now read-only.

Ingest method for igraph #14

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Ingest method for igraph #14

wants to merge 4 commits into from

Conversation

darrkj
Copy link
Contributor

@darrkj darrkj commented Dec 8, 2014

There is lots of sample data in the form of igraph objects and it is a common graph package in R. Adding the ability to easily push these to Neo4j makes storing these easier. It is also generic so there may be other common types of networks that are used in R which could be given there own ingest method.

@nicolewhite
Copy link
Owner

Thanks for another good idea. :) I will review it and request changes (if any) this weekend.

@nicolewhite
Copy link
Owner

I wonder if it would make more sense to incorporate this into importSample(), rather than writing a new function that does something similar.

@darrkj
Copy link
Contributor Author

darrkj commented Dec 15, 2014

I thought about that approach, but importSample seemed to be directed at a sample to get started quickly. I think it would make sense if it was import.cypher or import.file for the current samples, but this would allow you to also point to other cypher files. There were a few other network types I work with that pushed me to the other method, mainly the network class used in sna and the gexf class that comes out of gephi from rgexf. The importSample was not really setup for this since the functions dispatch on the graph class. I think there is a way to do it based on the class of multiple inputs or maybe just the second. This also makes me think I need to change something since I assume the graph object is just called graph which can create odd errors. I should require that as the first argument or check for something in the global env.

@nicolewhite
Copy link
Owner

I noticed you were assuming the graph object was called graph. It definitely needs to dispatch on the graph class. I am not aware of a way to dispatch on multiple arguments beyond the first - do you have examples for S3? If we can figure that out, I would be up for changing importSample to just import, and having the following:

import.default # this would work how importSample does
import.igraph # your function

What do you think? This would also leave it open for importing other things, like you mention a network class and gexf class:

import.gexf # TODO
import.network # TODO

Yours would then look like:

library(RNeo4j)
library(igraphdata)

neo4j = startGraph("http://localhost:7474/db/data/")
data(karate)
import(neo4j, karate, "KNOWS")

I'm not sure how we tell S3 methods to ignore the first argument passed and dispatch on the second, though.

There are also a few other things that I'd want to change. For example, you create two relationships for the un-directed graphs and I'm not sure if that's the best approach. I was also not sure what the domain property was for. But I'll leave that until we get some of the more high-level stuff figured out.

@darrkj
Copy link
Contributor Author

darrkj commented Dec 16, 2014

A good place to see ways to dispatch on things other than the first argument can be found at http://adv-r.had.co.nz/S3.html under inheritance towards the bottom.

That layout looks perfect.

I agree about the un-directed networks, and was interested in your thoughts.

The domain property is a way that I have used to separate graphs. For instance often I have many different networks loaded in Neo4j, they have no relation at all. Some may be congress votes while others are emails from some company. I almost use it like a schema or owner in an RDBMS. This property makes it easy to delete just that subgraph. So I can do things like this;

cypher(graph, "match (a)-[r]->(b) where r.domain = 'domain' delete r;")
cypher(graph, "match a where a.domain = 'domain' delete a;")

Which can also be done in one query like your clear function. But I query for movie data or airport data, or just delete the movie data and leave the airport data untouched.

@nicolewhite
Copy link
Owner

There's a hacky way we can do it. We'll have a method that dispatches on the graph class, then within that method we'll check the class of the second argument and dispatch on that:

import.graph <- function(graph, something) {
  if(class(something) == "character") {
    # My current importSample function
  } else if(class(something) == "igraph") {
    # Your function
  } else if(class(something) == "gexf") {
    # TODO
  } else {
    stop("some error")
  }
}

The link to Hadley's material seems to be about dispatching on an object with multiple classes and not the other way around.

@darrkj
Copy link
Contributor Author

darrkj commented Dec 29, 2014

In this example there is no reason to dispatch on the graph class. If you switch the order of the arguments you end up doing the same thing except you don't have the inner dispatch.

import = function(something, graph) UseMethod("import")
import.default # this would work how importSample does
import.igraph # ingest.igraph
import.gexf # TODO

@nicolewhite
Copy link
Owner

I don't like the domain argument; it isn't typical to hold several, unrelated subgraphs in one Neo4j instance. It seems like a hacky way to switch databases.

I want to dispatch on the graph class, because all other functions dispatch on the graph class. Switching the order would be confusing.

@happyshows
Copy link

@nicolewhite Hi Nicole, is there any progress being made on this thread. Being able to write an igraph object to Neo4j directly will greatly reduce the amount of adhoc work required on user side.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants