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

return order of node metrics #192

Closed
gvdr opened this issue Jul 8, 2021 · 6 comments
Closed

return order of node metrics #192

gvdr opened this issue Jul 8, 2021 · 6 comments

Comments

@gvdr
Copy link
Contributor

gvdr commented Jul 8, 2021

My workflow using EcologicalNetworks is often:

  • develop some {node, edge, graph, subgraph, ...}-level metric
  • compare it with metrics already developed in EcologicalNetworks

However, I'm never sure in which order EcologicalNetworks returns its values.

One thing that may be possible is to force functions such as centrality_degree to return species values in the same order with which adjacency assign species to rows (or columns).

An other way is to add an option to adjacency so that it return the species key in the right order, so that one can match.

PS I'm proposing this because I think that at the moment the order of rows in 'adjacencyandcentrality_...are not the same. I tried to test it comparing a hand made degree (rowsums / colsums of the adjacency matrix) and the vals out ofcentrality_...`. Yet, I may be wrong.

@gvdr
Copy link
Contributor Author

gvdr commented Jul 8, 2021

Or in simpler words through an example, if I define a function as:

using Chain, EcologicalNetworks

in_degrees = @chain unipartite_foodweb begin
    adjacency
    sum(_,dims = 2)
    vec
end

How do I reconcile its values with, say,

centrality_degree(unipartite_foodweb)

?

@tpoisot
Copy link
Member

tpoisot commented Jul 9, 2021

Most (all?) species-level functions will return a Dict, and you can't really trust the order of keys.

BUT the names returned by the species methods will always be in the correct order (you can use dims as a keyword for bipartite networks) re. the adjacency matrix (which is now sparse, by the way).

So a solution would be to use... I guess for (sp,pos) in enumerate(species(N)), to access the correct position or entry in a dictionary?

@tpoisot
Copy link
Member

tpoisot commented Jul 9, 2021

Just to add further information, adjacency is simply a wrapper for Array{} on the sparse matrix, so it should definitely be returning the columns/rows in order. But it's not used anywhere internally (I think).

@gvdr
Copy link
Contributor Author

gvdr commented Jul 9, 2021

It sounds promising.
If species(N) gives the right order than it's just a matter of zipping up the results accordingly.
I may end up writing an helper function for that, and contribute it.

@gvdr
Copy link
Contributor Author

gvdr commented Jul 12, 2021

Ok, what I've come up with is something like this:

function merge_metrics(adj_metric::A, EN_metric::E, species_web::Vector{MangalNode}) where {A <: Vector, E <: Dict{MangalNode,<:Any}}
    adj_metric_df = DataFrame([(sp.id, adj_metric[position]) for (position, sp) in enumerate(species_web)])
    EN_metric_df = DataFrame([(sp.id, EN_metric[sp]) for sp in species_web])
    metric_df = innerjoin(adj_metric_df,EN_metric_df; on = Symbol(1), makeunique = true)
    rename!(metric_df, [:Species_id, :adj_metric, :EN_metric])
    return metric_df
end

where:

  • adj_metric is a numeric vector of values computed from the adjacency matrix
  • EN_metric is a dictionary of values from a function such as degree in EcologicalNetworks
  • species_web is the vector of species in a web

It returns a DataFrame with the species id and the two metrics.

It's easy to provide an higher abstraction function such as:

merge_metrics(adj_metric::A, EN_metric::E, web::W) where {A <: Vector, E <: Dict{MangalNode,<:Any}, W <: AbstractEcologicalNetwork} = merge_metrics(adj_metric, EN_metric, species(web))

Do you think this is the right approach? Would you have tackled this differently?

PS one thing I don't fully like is the dependency on DataFrames...

@tpoisot
Copy link
Member

tpoisot commented Jul 20, 2021

My issue with this is that it might lead people to do something like nodelevel in bipartite, which leads to essentially fishing expeditions. The point of keeping things separate was to encourage users to pick the method they need.

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

No branches or pull requests

2 participants