Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unexpected behaviour when a layer has no intralayer links #3

Open
garciacallejas opened this issue Jan 8, 2025 · 0 comments
Open

Comments

@garciacallejas
Copy link

garciacallejas commented Jan 8, 2025

I am generating a series of in silico multilayer networks. It may be the case that in a given network, one or more layers will have nodes with valid interlayer links but no intralayer links. This would be coded in interlayer links appearing in the dataframe passed to the interlayer_links argument of create_multilayer_network, but that layer not appearing as an element of the list passed to list_of_layers. Note that that list is named, so the function should be able to identify which layers have valid intralayer links or not.

This, however, generates a wrong multilayer, whereby it creates intralayer links for the layer that should have none. I think it takes the elements of the list of intralayer links sequentially, without discarding the layers not present in that list. So, if I have three layers, where layer 2 has no intralayer links, that layer will not be present in the intralayer links list. But the function will assume that it is, assigning the intralayer links of layer 3 to layer 2 and leaving intralayer 3 empty.

Below is a minimal example to reproduce the behaviour. Thank you for your work on the package!
David

# multilayer minimal example

library(emln)
library(tidyverse)

# -------------------------------------------------------------------------
num.sp <- 3
sp.names <- paste("sp",sprintf("%02d", 1:num.sp),sep="")

num.patches <- 3
patch.names <- paste("patch",sprintf("%02d", 1:num.patches),sep="")

# -------------------------------------------------------------------------
# layers: species
# nodes: patches

# total number of interlayer links
non.zero.interlayer.links <- 20

# intralayer links per sp
non.zero.intralayer.links <- 2

# some species will not have intralayer links
sp.without.intra <- 2
sp.without.intra.names <- sp.names[sp.without.intra]

# -------------------------------------------------------------------------
# layer attributes
layer_attributes <- tibble(layer_id = 1:num.sp, layer_name = sp.names)

# -------------------------------------------------------------------------
# interlayer links in a dataframe

my.interlayer.df <- expand_grid(layer_from = sp.names,node_from = patch.names,layer_to = sp.names, node_to = patch.names) %>%
  subset(layer_from != layer_to)

my.interlayer.df$weight <- 0
my.interlayer.df$weight[sample(nrow(my.interlayer.df),size = non.zero.interlayer.links,replace = F)] <- runif(non.zero.interlayer.links,0.1,0.5)

# -------------------------------------------------------------------------
# intralayer links in a list

my.intralayer.list <- list()
my.intralayer.names <- NULL
for(i.sp in 1:length(sp.names)){
  
  # only assign intralayer links to certain species
  if(!i.sp %in% sp.without.intra){
  my.intra.df <- expand_grid(from = patch.names, to = patch.names) %>%
    subset(from != to)
  my.intra.df$weight <- NA
  my.intra.df$weight[sample(nrow(my.intra.df),size = non.zero.intralayer.links,replace = F)] <- runif(non.zero.intralayer.links,0.1,0.5)
  
  my.intra.df.clean <- subset(my.intra.df, !is.na(weight))
  my.intralayer.list[[length(my.intralayer.list)+1]] <- my.intra.df.clean
  my.intralayer.names[length(my.intralayer.names)+1] <- sp.names[i.sp]
  }# if !sp in sp.without.intra
}# for i.sp

names(my.intralayer.list) <- my.intralayer.names

# -------------------------------------------------------------------------

test.multilayer <- NA
try(test.multilayer <- create_multilayer_network(list_of_layers = my.intralayer.list,
                                                 interlayer_links = my.interlayer.df,
                                                 layer_attributes = layer_attributes,
                                                 bipartite = F,
                                                 directed = T))
multilayer.link.list <- test.multilayer$extended

no.intra.sp.links <- subset(multilayer.link.list, layer_from == sp.without.intra.names & layer_to == sp.without.intra.names)

# check that no.intra.sp.links should be empty, but it is not.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant