Home > Blockchain >  lapply if some input values in a list are NULL
lapply if some input values in a list are NULL

Time:10-15

I have a list with matrices of different sizes that looks like this:

> MDP$B
     [,1]       [,2]       [,3]       [,4]      
[1,] numeric,4  NULL       NULL       NULL      
[2,] numeric,16 numeric,16 numeric,16 numeric,16

The following works with previous lists and also works, if I only apply it to e.g. [[1,1]] in the upper list, so the NULL values are the problem.

if(isfield(MDP,"b")){              
  MDP$b = lapply(MDP$b,col_norm)  
} else{
  MDP$b = lapply(MDP$B,col_norm)
}  

The function col_norm looks like this and normalizes colum vectors:

col_norm = function(x){t(t(x)/colSums(x))}

I get the error x must be numeric. Is there a way to make lapply just skip the NULL values? OR is it possible to fully delete [1,2],[1,3] and [1,4], so that the problem can`t occur?

NOTE: it was supposeds to say isfield(MDP, "b") not "b1", sorry for confusion.

SOLUTION BY @Roland: You can always use an anonymous function function(x) if (!is.null(x)) col_norm(x) else NULL. – Roland

Final line looks like this:

MDP$B = lapply(MDP$B,function(x) if (!is.null(x)) col_norm(x) else NULL)

I had to redim the list with "dim(MDP$B) = matrix(c(2,4))", but thats fine :))

dim(MDP$B) = matrix(c(2,4))

SOLUTION TO THAT also by @Roland: use: MDP$b[] <- lapply(MDP$b, (x) if (!is.null(x)) col_norm(x) else NULL)

CodePudding user response:

In colSums function there is a na.rm parameter:

col_norm = function(x){t(t(x)/colSums(x, na.rm=TRUE))}

Or if they are NULL, also do:

col_norm = function(x){t(t(x)/colSums(replace(x, NULL, NA), na.rm=TRUE))}

CodePudding user response:

Create an anonymous function that checks if it is passed NULL. You also may want to use [<- instead of = to assign into the matrix and preserve its class and dimensions. Both together:

MDP$b[] <- lapply(MDP$b, \(x) if (!is.null(x)) col_norm(x) else NULL)
  • Related