9
$\begingroup$

Graph objects support both custom properties, which do not have special meanings, and standard properties, which may be used by some functions.

When importing from formats such as GraphML, we usually get a result with custom properties.

What is the simplest way to remap one property to another, e.g. to remap a custom property to a standard one so it can be used with various functions?


Example: Let's get Zachary's karate club network with edge weights and vertex names from here: http://nexus.igraph.org/api/dataset_info?id=1&format=html

g = Import[
  "http://nexus.igraph.org/api/dataset?id=1&format=GraphML", {"ZIP", "karate.GraphML"}]

I can remap "name" to VertexLabels and "weights" to EdgeWeight like this:

sp[prop_][g_] := SetProperty[g, prop]

g2 = g // 
   sp[EdgeWeight -> (PropertyValue[{g, #}, "weight"] & /@ EdgeList[g])] // 
   sp[VertexLabels -> (# -> PropertyValue[{g, #}, "name"] & /@ VertexList[g])]

I do find this quite tedious though. I am wondering if there are easier, more streamlined ways to do it.

For example, with igraph this is usually as easy as g.betweeness(weights="weight") (Python) to use the "weight" attribute as edge weights for a betweenness calculation. I know that WeightedAdjacencyMatrix does support such a simple syntax: WeightedAdjacencyMatrix[g, EdgeWeight -> "weight"] uses the "weight" attribute for the matrix. But I don't know if there are simple syntaxes like this in other situations.

$\endgroup$

2 Answers 2

4
$\begingroup$

Slightly more cumbersome alternative to your sp (hopefully little less tedious to use):

ClearAll[mapF]
mapF[pr1_ -> pr2_][g_] := SetProperty[g, 
   pr1 -> Cases[Options@g, Rule[a_, {___, Rule[pr2, v_], ___}] :> Rule[a, v], Infinity]];

mapF[r : (_ -> _) ..][g_] := Fold[mapF[#2][#] &, g, {r}];

g3 = g // mapF[VertexLabels -> "name"]

Mathematica graphics

g4 = g // mapF[VertexLabels -> "name", EdgeWeight -> "weight", VertexSize -> "Faction"]; 

PropertyValue[{g4, #}, VertexLabels] & /@ VertexList[g4]

Mathematica graphics

PropertyValue[g4, EdgeWeight]

{"4", "5", "3", "3", "3", "3", "2", "2", "2", "3", "1", "3", "2", "2", "2", "2", "6", "3", "4", "5", "1", "2", "2", "2", "3", "4", "5", "1", "3", "2", "2", "2", "3", "3", "3", "2", "3", "5", "3", "3", "3", "3", "3", "4", "2", "3", "3", "2", "3", "4", "1", "2", "1", "3", "1", "2", "3", "5", "4", "3", "5", "4", "2", "3", "2", "7", "4", "2", "4", "2", "2", "4", "2", "3", "3", "4", "4", "5"}

Note: the values of weight are strings.

$\endgroup$
2
$\begingroup$

With IGraph/M, we can transfer the value of one property into another one. For example, to copy the "weight" values into EdgeWeight, use

IGEdgeMap[Identity, EdgeWeight -> IGEdgeProp["weight"], g]

This does not remove "weight". It only copies its values into another property.

There is also an operator form for these functions, to allow chaining:

g // IGEdgeMap[#&, EdgeWeight -> IGEdgeProp["weight"]] // IGVertexMap[#&, VertexLabels -> IGVertexProp["name"]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.