Problem with bipartite network where one of the modes has a single vertex.
Closed this issue · 3 comments
Hello,
I'm getting an error when I try to call btergm() on a list of two-mode networks where one of the modes has a single vertex.
The error I get is:
Error in nr[j] != nr.net[j] :
comparison of these types is not implemented
I'm almost certain the problem is occurring because R is converting each one-row sociomatrix into a numeric vector, which causes tergmprepare() to fail. When I call btergm() on a list of one-mode networks (whose sociomatrices have multiple rows and columns) it works fine.
Here's example code that reproduces the error.
node_vars <- data.frame(
name = c("Actor 1", "Actor 1", "Actor 2", "Actor 2", "Actor 3", "Actor 3"),
var1 = c("A", "A", "A", "A", "A", "B"),
year = c(2000, 2001, 2000, 2001, 2000, 2001),
type = c(TRUE, TRUE, FALSE, FALSE, FALSE, FALSE)
)
node_var_list <- node_vars %>%
group_by(year) %>%
group_split()
edge_vars <- data.frame(
name1 = c("Actor 1", "Actor 1", "Actor 1"),
name2 = c("Actor 2", "Actor 2", "Actor 3"),
year = c(2000, 2001, 2000)
)
edge_var_list <- edge_vars %>%
group_by(year) %>%
group_split()
# Create bipartite networks
test_net1_bp <- as.network(x = edge_var_list[[1]], vertices = node_var_list[[1]],
directed = FALSE, bipartite = TRUE, bipartite_col = "type")
test_net2_bp <- as.network(x = edge_var_list[[2]], vertices = node_var_list[[2]],
directed = FALSE, bipartite = TRUE, bipartite_col = "type")
test_nets_bp <- list(test_net1_bp, test_net2_bp)
tergmprepare(test_nets_bp[1:2] ~ edges + b1nodematch("var1") ) # It doesn't work
# Create one-mode networks
test_net1 <- as.network(x = edge_var_list[[1]], vertices = node_var_list[[1]],
directed = FALSE, bipartite = FALSE)
test_net2 <- as.network(x = edge_var_list[[2]], vertices = node_var_list[[2]],
directed = FALSE, bipartite = FALSE)
test_nets <- list(test_net1, test_net2)
tergmprepare(test_nets[1:2] ~ edges + nodematch("var1")) # It works
Do you have any suggestions for how to solve this issue?
Thank you.
Thanks for reporting this issue.
Indeed, the problem occurs here. The list of networks is converted there into a list of matrices using as.matrix
from the network
package, and then nrow
checks the number of rows of each matrix.
The problem seems to be that as.matrix
does not actually return a matrix. We can verify this using your example:
class(as.matrix(test_net1_bp))
returns numeric
instead of matrix
, and
dim(as.matrix(test_net1_bp))
returns NULL
.
My interpretation is that the as.matrix.network.adjacency
function in the network
package should, but doesn't, return a matrix (though I am not sure if this is the right one, given that you provided an edge list to begin with). So I'd play with the code there and see what you need to change in that function (or perhaps the other functions in that file) to get the desired effect of as.matrix
with your network
object. Perhaps worth reporting there as well as a potential bug that may need to be reviewed. Not sure what the problem is exactly, but my intuition tells me that if a function is called as.matrix
and it doesn't return a matrix, something must be wrong.
That said, I have to admit that I did not pay particular attention to edge lists and their difficulties when I wrote btergm
and tergmprepare
. So my general advice would be to use bipartite matrices when dealing with data for TERGMs. They should have n
rows and m
columns, where n
is the number of actors and m
is the number of events. This is how I would approach the problem. Let me know if you do this and there is still some issue. Admittedly, support for bipartite networks was not tested very thoroughly, but it should work. If you do have a minimal and self-contained example for that usage scenario, I would be glad if you could post it here because I could use it as a unit test in order to ensure that future changes don't break the bipartite example. Thanks.
I'll close the issue here and defer to the issue in the network
package I referenced above.
Should be fixed in statnet/network@27c8857.