There's already work on this going on (see graph_data.R#L44). Ideally, we need a function that generates a raw/generic graph format made of basic R structures (at most dgCMatrix objects).
Why
The idea is to use a generic class of graph throughout the package in the following form:
This way it will be easier to extend netdiffuseR to other packages/formats
Details
The generic class should be, of course, a generalization of a annotated networks with some special attributes. For now, I see:
Dynamic graph object: a list of edgelists (that way multiple edges can be stored)
Vertex attributes: A list of data frames.
Vertex labels: A character vector with vertices names.
Slices labels: A character vector with slices names
Metadata:
Directed: Logical scalar
Valued: Logical scalar
Autolinks: Logical scalar
Name: Character scalar
Description: Character scalar
Original class: name of the class
Furthermore, this is more a list of possible outcomes, since it might be more efficient to, instead of fully generating a generic graph. It could be a function that reads/writes info depending on the graph class. For example:
net_readfuns <- function(graph) {
gclass <- class(graph)
funname <- paste0("net_readfuns_", gclass[1])
# Checking if there is methods
if (!exists(funname, envir="netdiffuseR"))
stop("No functions defined for graph of class -", gclass,"-.")
return(get(funname, envir = "netdiffuseR"))
}
Or even better, a S3 class object with the following structure
graph: The graph object
gclass: Character scalar, class(graph)
read: A list of reading functions:
adjmat: A function that returns as list with objects of class dgCMatrix (adjmats).
edgelist: A function that returns a list with objects of class matrix: Edgelist.
vertex: A function that returnrs a matrix of size n*2 with ids and labels.
vertex_attrs: A function that returns a data frame with vertex attributes.
graph_attrs: A function that returns a data frame with graph attributes
...
write: A list of writing functions:
...
meta A list with meta data.
Directed: Logical scalar
Valued: Logical scalar
Autolinks: Logical scalar
The read/write functions can be specified as a lose object per class name, for example,
# Function to capture specs
readwrite_ <- function(graph) {
gclass <- class(graph)
ans <- paste0("readwrite_", gclass[1])
# Checking if there is methods
if (!exists(ans, envir="netdiffuseR"))
stop("No functions defined for graph of class -", gclass,"-.")
ans <- get(funname, envir = "netdiffuseR")
ans$graph <- graph
return(ans)
}
# igraph specs
readwrite_igraph <- list(
graph = NULL,
gclass = "igraph",
read = list(
adjmat = function(x) {igraph::as_adjmat(x)},
...
),
...
)
Or perhaps, a more elegant way of doing this would be by crating a single graph_io object as follows:
What
There's already work on this going on (see graph_data.R#L44). Ideally, we need a function that generates a raw/generic graph format made of basic R structures (at most dgCMatrix objects).
Why
The idea is to use a generic class of graph throughout the package in the following form:
This way it will be easier to extend netdiffuseR to other packages/formats
Details
The generic class should be, of course, a generalization of a annotated networks with some special attributes. For now, I see:
Furthermore, this is more a list of possible outcomes, since it might be more efficient to, instead of fully generating a generic graph. It could be a function that reads/writes info depending on the graph class. For example:
Or even better, a S3 class object with the following structure
graph
: The graph objectgclass
: Character scalar,class(graph)
read
: A list of reading functions:adjmat
: A function that returns as list with objects of classdgCMatrix
(adjmats).edgelist
: A function that returns a list with objects of classmatrix
: Edgelist.vertex
: A function that returnrs a matrix of sizen*2
with ids and labels.vertex_attrs
: A function that returns a data frame with vertex attributes.graph_attrs
: A function that returns a data frame with graph attributeswrite
: A list of writing functions:meta
A list with meta data.The read/write functions can be specified as a lose object per class name, for example,
Or perhaps, a more elegant way of doing this would be by crating a single graph_io object as follows: