This is a simple graph database in SQLite, inspired by “Denis Papathanasiou’s simple-graph project”, however this is written in R. This package is fully compatible with the python equivalant and interoperable. There are minor differences in the API, but it is largely identical.


Similar to the python library, the schema consists of just two structures:




Basic Functions

The R package provides convenience functions for atomic transactions to add, delete, connect, and search for nodes.

Any single node or path of nodes can also be depicted graphically by using the visualize function within the database script to generate dot files, which in turn can be converted to images with Graphviz.


Once loading the package in R, we can create, upsert, and connect people from the early days of Apple Computer. The resulting database will be saved to a SQLite file named apple.sqlite:

apple <- "apple.sqlite"
atomic(apple, add_node(list("name" = "Apple Computer Company", "type" = c("company", "start-up"), "founded" = "April 1, 1976"), 1))
atomic(apple, add_node(list("name" = "Steve Wozniak", "type" = c("person", "engineer", "founder")), 2))
atomic(apple, add_node(list("name" = "Steve Jobs", "type" = c("person", "designer", "founder")), 3))
atomic(apple, add_node(list("name" = "Ronald Wayne", "type" = c("person", "administrator", "founder")), 4))
atomic(apple, add_node(list("name" = "Mike Markkula", "type" = c("person", "investor")), 5))
atomic(apple, connect_nodes(2, 1, list("action" = "founded")))
atomic(apple, connect_nodes(3, 1, list("action" = "founded")))
atomic(apple, connect_nodes(4, 1, list("action" = "founded")))
atomic(apple, connect_nodes(5, 1, list("action" = "invested", "equity" = 80000, "debt" = 170000)))
atomic(apple, connect_nodes(1, 4, list("action" = "divested", "amount" = 800, "date" = "April 12, 1976")))
atomic(apple, connect_nodes(2, 3))
atomic(apple, upsert_node(2, list("nickname" = "Woz"), apple))

The nodes can be searched by their ids or any other combination of attributes (either as strict equality, or using search_like in combination with search_starts_with or search_contains):

atomic(apple, find_node(1))
{'name': 'Apple Computer Company', 'type': ['company', 'start-up'], 'founded': 'April 1, 1976', 'id': 1}
atomic(apple, find_nodes({'name': 'Steve'}, "search_like", "search_starts_with"))
[{'name': 'Steve Wozniak', 'type': ['person', 'engineer', 'founder'], 'id': 2, 'nickname': 'Woz'}, {'name': 'Steve Jobs', 'type': ['person', 'designer', 'founder'], 'id': 3}]

Paths through the graph can be discovered with a starting node id, and an optional ending id; the default neighbor expansion is nodes connected nodes in either direction, but that can changed by specifying either find_outbound_neighbors or find_inbound_neighbors instead:

traverse(apple, 2, 3)
[2, 3]
traverse(apple, 4, 5)
[4, 1, 5]
traverse(apple, 5, neighbors_fn="find_inbound_neighbors")
traverse(apple, 5, neighbors_fn="find_outbound_neighbors")
[5, 1, 4]
traverse(apple, 5, neighbors_fn="find_neighbors")
[5, 1, 4, 3, 2]

Any path or list of nodes can rendered graphically by using the visualize function. This command produces dot files, which are also rendered as images with Graphviz:

visualize(apple, 'apple.dot', c(4, 1, 5))

There are display options to help refine what is produced:

visualize(apple, 'apple.dot', c(4, 1, 5), exclude_node_keys=c('type'), hide_edge_key=TRUE)