Chao Liu
2022-Sep-21 19:20 UTC
[R] Error in if (class(networks) == "matrix") from a function
Dear R-Help community, This is a crosspost on SO but I've had no luck so far. So I have a function which computes a centrality index for the nodes in a network or matrix. Here is the function: library(igraph) #load package igraph centrality <- function (networks, type = c("indegree", "outdegree", "freeman", "betweenness", "flow", "closeness", "eigenvector", "information", "load", "bonpow"), directed = TRUE, lag = 0, rescale = FALSE, center = FALSE, coefname = NULL, ...) { if (is.null(directed) || !is.logical(directed)) { stop("'directed' must be TRUE or FALSE.") } else if (length(directed) != 1) { stop("The 'directed' argument must contain a single logical value only.") } else if (directed == FALSE) { gmode <- "graph" } else { gmode <- "digraph" } objects <- checkDataTypes(y = NULL, networks = networks, lag = lag) centlist <- list() for (i in 1:objects$time.steps) { if (type[1] == "indegree") { cent <- degree(objects$networks[[i]], gmode = gmode, cmode = "indegree", rescale = rescale, ...) } else if (type[1] == "outdegree") { cent <- degree(objects$networks[[i]], gmode = gmode, cmode = "outdegree", rescale = rescale, ...) } else if (type[1] == "freeman") { cent <- degree(objects$networks[[i]], gmode = gmode, cmode = "freeman", rescale = rescale, ...) } else if (type[1] == "betweenness") { cent <- betweenness(objects$networks[[i]], gmode = gmode, rescale = rescale, ...) } else if (type[1] == "flow") { cent <- flowbet(objects$networks[[i]], gmode = gmode, rescale = rescale, ...) } else if (type[1] == "closeness") { cent <- closeness(objects$networks[[i]], gmode = gmode, rescale = rescale, ...) } else if (type[1] == "eigenvector") { cent <- evcent(objects$networks[[i]], gmode = gmode, rescale = rescale, ...) } else if (type[1] == "information") { cent <- infocent(objects$networks[[i]], gmode = gmode, rescale = rescale, ...) } else if (type[1] == "load") { cent <- loadcent(objects$networks[[i]], gmode = gmode, rescale = rescale, ...) } else if (type[1] == "bonpow") { cent <- bonpow(objects$networks[[i]], gmode = gmode, rescale = rescale, tol = 1e-20, ...) } else { stop("'type' argument was not recognized.") } centlist[[i]] <- cent } time <- numeric() y <- numeric() for (i in 1:objects$time.steps) { time <- c(time, rep(i, objects$n[[i]])) if (is.null(centlist[[i]])) { y <- c(y, rep(NA, objects$n[[i]])) } else { if (center == TRUE) { centlist[[i]] <- centlist[[i]] - mean(centlist[[i]], na.rm = TRUE) } y <- c(y, centlist[[i]]) } } if (is.null(coefname) || !is.character(coefname) || length(coefname) > 1) { coeflabel <- "" } else { coeflabel <- paste0(".", coefname) } if (lag == 0) { laglabel <- "" } else { laglabel <- paste0(".lag", paste(lag, collapse = ".")) } label <- paste0(type[1], coeflabel, laglabel) dat <- data.frame(y, time = time, node = objects$nodelabels) dat$node <- as.character(dat$node) colnames(dat)[1] <- label attributes(dat)$lag <- lag return(dat)} Here is the matrix: dat <- read.table(text="A B #this is edgelist 1 2 1 3 1 2 2 1 2 3 3 1 3 2 3 1", header=TRUE) datmat <- as.matrix(get.adjacency(graph.edgelist(as.matrix(dat), directed=TRUE))) #this is the matrix colnames(datmat) <- c("1", "2", "3") #rename the columns When I applied the function to a matrix centrality(datmat,type="flow",center=TRUE), it returns the error: Error in if (class(networks) == "matrix") { : the condition has length > 1 What is the cause of this error? How to fix it? Any help will be greatly appreciated! Best, Chao [[alternative HTML version deleted]]
Eric Berger
2022-Sep-21 19:26 UTC
[R] Error in if (class(networks) == "matrix") from a function
In R 4.2.0 there is a significant change. When you use an if() statement with a condition of length > 1 this now reports an error. e.g. this link mentions it as a change https://www.jumpingrivers.com/blog/new-features-r420/ In your case this is because class(obj) can return a character vector of length > 1 (all the classes). One possible workaround would be: if ( "matrix" %in% class(networks) ) ... HTH, Eric On Wed, Sep 21, 2022 at 10:21 PM Chao Liu <psychaoliu at gmail.com> wrote:> Dear R-Help community, > > This is a crosspost on SO but I've had no luck so far. So I have a function > which computes a centrality index for the nodes in a network or matrix. > Here is the function: > > library(igraph) #load package igraph > centrality <- function (networks, type = c("indegree", "outdegree", > "freeman", > "betweenness", "flow", "closeness", "eigenvector", "information", > "load", "bonpow"), directed = TRUE, lag = 0, rescale = FALSE, > center = FALSE, coefname = NULL, ...) { > if (is.null(directed) || !is.logical(directed)) { > stop("'directed' must be TRUE or FALSE.") > } > else if (length(directed) != 1) { > stop("The 'directed' argument must contain a single logical > value only.") > } > else if (directed == FALSE) { > gmode <- "graph" > } > else { > gmode <- "digraph" > } > objects <- checkDataTypes(y = NULL, networks = networks, > lag = lag) > centlist <- list() > for (i in 1:objects$time.steps) { > if (type[1] == "indegree") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "indegree", rescale = rescale, ...) > } > else if (type[1] == "outdegree") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "outdegree", rescale = rescale, ...) > } > else if (type[1] == "freeman") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "freeman", rescale = rescale, ...) > } > else if (type[1] == "betweenness") { > cent <- betweenness(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "flow") { > cent <- flowbet(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "closeness") { > cent <- closeness(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "eigenvector") { > cent <- evcent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "information") { > cent <- infocent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "load") { > cent <- loadcent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "bonpow") { > cent <- bonpow(objects$networks[[i]], gmode = gmode, > rescale = rescale, tol = 1e-20, ...) > } > else { > stop("'type' argument was not recognized.") > } > centlist[[i]] <- cent > } > time <- numeric() > y <- numeric() > for (i in 1:objects$time.steps) { > time <- c(time, rep(i, objects$n[[i]])) > if (is.null(centlist[[i]])) { > y <- c(y, rep(NA, objects$n[[i]])) > } > else { > if (center == TRUE) { > centlist[[i]] <- centlist[[i]] - mean(centlist[[i]], > na.rm = TRUE) > } > y <- c(y, centlist[[i]]) > } > } > if (is.null(coefname) || !is.character(coefname) || length(coefname) > > 1) { > coeflabel <- "" > } > else { > coeflabel <- paste0(".", coefname) > } > if (lag == 0) { > laglabel <- "" > } > else { > laglabel <- paste0(".lag", paste(lag, collapse = ".")) > } > label <- paste0(type[1], coeflabel, laglabel) > dat <- data.frame(y, time = time, node = objects$nodelabels) > dat$node <- as.character(dat$node) > colnames(dat)[1] <- label > attributes(dat)$lag <- lag > return(dat)} > > Here is the matrix: > > dat <- read.table(text="A B #this is edgelist > 1 2 > 1 3 > 1 2 > 2 1 > 2 3 > 3 1 > 3 2 > 3 1", header=TRUE) > datmat <- as.matrix(get.adjacency(graph.edgelist(as.matrix(dat), > directed=TRUE))) #this is the matrix > colnames(datmat) <- c("1", "2", "3") #rename the columns > > When I applied the function to a matrix > centrality(datmat,type="flow",center=TRUE), it returns the error: > > Error in if (class(networks) == "matrix") { : > the condition has length > 1 > > What is the cause of this error? How to fix it? Any help will be greatly > appreciated! > > > Best, > > Chao > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Andrew Simmons
2022-Sep-21 19:29 UTC
[R] Error in if (class(networks) == "matrix") from a function
In general, you should be using inherits(netwotks, "matrix") or is(networks, "matrix") instead of class() = Your function fails because your object has multiple classes so class=returns multiple logical values so if will fail. But inherits or is will return one logical value, so if will not raise an error. On Wed., Sep. 21, 2022, 15:21 Chao Liu, <psychaoliu at gmail.com> wrote:> Dear R-Help community, > > This is a crosspost on SO but I've had no luck so far. So I have a function > which computes a centrality index for the nodes in a network or matrix. > Here is the function: > > library(igraph) #load package igraph > centrality <- function (networks, type = c("indegree", "outdegree", > "freeman", > "betweenness", "flow", "closeness", "eigenvector", "information", > "load", "bonpow"), directed = TRUE, lag = 0, rescale = FALSE, > center = FALSE, coefname = NULL, ...) { > if (is.null(directed) || !is.logical(directed)) { > stop("'directed' must be TRUE or FALSE.") > } > else if (length(directed) != 1) { > stop("The 'directed' argument must contain a single logical > value only.") > } > else if (directed == FALSE) { > gmode <- "graph" > } > else { > gmode <- "digraph" > } > objects <- checkDataTypes(y = NULL, networks = networks, > lag = lag) > centlist <- list() > for (i in 1:objects$time.steps) { > if (type[1] == "indegree") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "indegree", rescale = rescale, ...) > } > else if (type[1] == "outdegree") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "outdegree", rescale = rescale, ...) > } > else if (type[1] == "freeman") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "freeman", rescale = rescale, ...) > } > else if (type[1] == "betweenness") { > cent <- betweenness(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "flow") { > cent <- flowbet(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "closeness") { > cent <- closeness(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "eigenvector") { > cent <- evcent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "information") { > cent <- infocent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "load") { > cent <- loadcent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "bonpow") { > cent <- bonpow(objects$networks[[i]], gmode = gmode, > rescale = rescale, tol = 1e-20, ...) > } > else { > stop("'type' argument was not recognized.") > } > centlist[[i]] <- cent > } > time <- numeric() > y <- numeric() > for (i in 1:objects$time.steps) { > time <- c(time, rep(i, objects$n[[i]])) > if (is.null(centlist[[i]])) { > y <- c(y, rep(NA, objects$n[[i]])) > } > else { > if (center == TRUE) { > centlist[[i]] <- centlist[[i]] - mean(centlist[[i]], > na.rm = TRUE) > } > y <- c(y, centlist[[i]]) > } > } > if (is.null(coefname) || !is.character(coefname) || length(coefname) > > 1) { > coeflabel <- "" > } > else { > coeflabel <- paste0(".", coefname) > } > if (lag == 0) { > laglabel <- "" > } > else { > laglabel <- paste0(".lag", paste(lag, collapse = ".")) > } > label <- paste0(type[1], coeflabel, laglabel) > dat <- data.frame(y, time = time, node = objects$nodelabels) > dat$node <- as.character(dat$node) > colnames(dat)[1] <- label > attributes(dat)$lag <- lag > return(dat)} > > Here is the matrix: > > dat <- read.table(text="A B #this is edgelist > 1 2 > 1 3 > 1 2 > 2 1 > 2 3 > 3 1 > 3 2 > 3 1", header=TRUE) > datmat <- as.matrix(get.adjacency(graph.edgelist(as.matrix(dat), > directed=TRUE))) #this is the matrix > colnames(datmat) <- c("1", "2", "3") #rename the columns > > When I applied the function to a matrix > centrality(datmat,type="flow",center=TRUE), it returns the error: > > Error in if (class(networks) == "matrix") { : > the condition has length > 1 > > What is the cause of this error? How to fix it? Any help will be greatly > appreciated! > > > Best, > > Chao > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Rui Barradas
2022-Sep-21 19:35 UTC
[R] Error in if (class(networks) == "matrix") from a function
Hello, Check what class(datmat) returns and use ?inherits instead. class(datmat) #[1] "matrix" "array" inherits(datmat, "matrix") #[1] TRUE Also, the error the posted code gives is centrality(datmat,type="flow",center=TRUE) Error in checkDataTypes(y = NULL, networks = networks, lag = lag) : could not find function "checkDataTypes" but I assume you have function checkDataTypes somewhere in your session, the problem should be solved with inherits(). Hope this helps, Rui Barradas ?s 20:20 de 21/09/2022, Chao Liu escreveu:> Dear R-Help community, > > This is a crosspost on SO but I've had no luck so far. So I have a function > which computes a centrality index for the nodes in a network or matrix. > Here is the function: > > library(igraph) #load package igraph > centrality <- function (networks, type = c("indegree", "outdegree", "freeman", > "betweenness", "flow", "closeness", "eigenvector", "information", > "load", "bonpow"), directed = TRUE, lag = 0, rescale = FALSE, > center = FALSE, coefname = NULL, ...) { > if (is.null(directed) || !is.logical(directed)) { > stop("'directed' must be TRUE or FALSE.") > } > else if (length(directed) != 1) { > stop("The 'directed' argument must contain a single logical > value only.") > } > else if (directed == FALSE) { > gmode <- "graph" > } > else { > gmode <- "digraph" > } > objects <- checkDataTypes(y = NULL, networks = networks, > lag = lag) > centlist <- list() > for (i in 1:objects$time.steps) { > if (type[1] == "indegree") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "indegree", rescale = rescale, ...) > } > else if (type[1] == "outdegree") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "outdegree", rescale = rescale, ...) > } > else if (type[1] == "freeman") { > cent <- degree(objects$networks[[i]], gmode = gmode, > cmode = "freeman", rescale = rescale, ...) > } > else if (type[1] == "betweenness") { > cent <- betweenness(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "flow") { > cent <- flowbet(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "closeness") { > cent <- closeness(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "eigenvector") { > cent <- evcent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "information") { > cent <- infocent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "load") { > cent <- loadcent(objects$networks[[i]], gmode = gmode, > rescale = rescale, ...) > } > else if (type[1] == "bonpow") { > cent <- bonpow(objects$networks[[i]], gmode = gmode, > rescale = rescale, tol = 1e-20, ...) > } > else { > stop("'type' argument was not recognized.") > } > centlist[[i]] <- cent > } > time <- numeric() > y <- numeric() > for (i in 1:objects$time.steps) { > time <- c(time, rep(i, objects$n[[i]])) > if (is.null(centlist[[i]])) { > y <- c(y, rep(NA, objects$n[[i]])) > } > else { > if (center == TRUE) { > centlist[[i]] <- centlist[[i]] - mean(centlist[[i]], > na.rm = TRUE) > } > y <- c(y, centlist[[i]]) > } > } > if (is.null(coefname) || !is.character(coefname) || length(coefname) > > 1) { > coeflabel <- "" > } > else { > coeflabel <- paste0(".", coefname) > } > if (lag == 0) { > laglabel <- "" > } > else { > laglabel <- paste0(".lag", paste(lag, collapse = ".")) > } > label <- paste0(type[1], coeflabel, laglabel) > dat <- data.frame(y, time = time, node = objects$nodelabels) > dat$node <- as.character(dat$node) > colnames(dat)[1] <- label > attributes(dat)$lag <- lag > return(dat)} > > Here is the matrix: > > dat <- read.table(text="A B #this is edgelist > 1 2 > 1 3 > 1 2 > 2 1 > 2 3 > 3 1 > 3 2 > 3 1", header=TRUE) > datmat <- as.matrix(get.adjacency(graph.edgelist(as.matrix(dat), > directed=TRUE))) #this is the matrix > colnames(datmat) <- c("1", "2", "3") #rename the columns > > When I applied the function to a matrix > centrality(datmat,type="flow",center=TRUE), it returns the error: > > Error in if (class(networks) == "matrix") { : > the condition has length > 1 > > What is the cause of this error? How to fix it? Any help will be greatly > appreciated! > > > Best, > > Chao > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.