Re: [R] Error in if (class(networks) == "matrix") from a function

2022-09-22 Thread Chao Liu
Thank you Eric, Andrew, Rui and Martin for all your help and advice. I did
learn some good practices under the new R version!

Best,

Chao

On Thu, Sep 22, 2022 at 5:53 AM Martin Maechler 
wrote:

> > 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 
> 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 <- 

Re: [R] Error in if (class(networks) == "matrix") from a function

2022-09-22 Thread Martin Maechler
> 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  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 

Re: [R] Error in if (class(networks) == "matrix") from a function

2022-09-21 Thread Rui Barradas

Hello,

In my previous I forgot that this, for matrices to have 2 classes , is 
relatively new. It was introduced in R 4.0.0. From the News file [1], 
point 2:



R News
[R logo] CHANGES IN 4.0.0
SIGNIFICANT USER-VISIBLE CHANGES

matrix objects now also inherit from class "array", so e.g., 
class(diag(1)) is c("matrix", "array"). This invalidates code 
incorrectly assuming that class(matrix_obj)) has length one.



So the R Core Team did an excelent job once again and warned R users. 
This was a major R version, where changes like this generally happen and 
are anounced with antecipation. (I remeber to have seen it but cannot 
place it.) Old code needs to be changed, it might break.



[1] https://cran.r-project.org/bin/windows/base/old/4.0.0/NEWS.R-4.0.0.html

Hope this helps,

Rui Barradas

Às 20:35 de 21/09/2022, Rui Barradas escreveu:

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 <- 

Re: [R] Error in if (class(networks) == "matrix") from a function

2022-09-21 Thread Rui Barradas

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]]


Re: [R] Error in if (class(networks) == "matrix") from a function

2022-09-21 Thread Andrew Simmons
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,  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]]
>
> 

Re: [R] Error in if (class(networks) == "matrix") from a function

2022-09-21 Thread Eric Berger
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  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!
>
>