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]]
Martin Maechler
2022-Sep-22 09:53 UTC
[R] Error in if (class(networks) == "matrix") from a function
>>>>> Eric Berger >>>>> on Wed, 21 Sep 2022 22:26:39 +0300 writes:> 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) ) ... Yes, however, in general, the recommendation in the related R blog, would have been if(inherits(networks, "matrix")) which I consider better *correctly readable* (and also expect to be more efficient). Lastly, in this special case, I'd try if(is.matrix(networks)) i.e., I'd try to see if the fast is.matrix(.) applies to your 'networks' (and I'm guessing "yes" with high confidence ..). Martin > 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]] > ______________________________________________ > 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.