lapply 如果列表中的某些输入值为 NULL

lapply if some input values in a list are NULL

我有一个包含不同大小矩阵的列表,如下所示:

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

以下内容适用于之前的列表,并且如果我仅将其应用于例如[[1,1]] 在上面的列表中,所以 NULL 值是问题所在。

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

函数 col_norm 看起来像这样并对列向量进行归一化:

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

我收到错误 x 必须是数字。有没有办法让 lapply 跳过 NULL 值?或者是否可以完全删除 [1,2]、[1,3] 和 [1,4],这样问题就不会发生?

注意:应该说 isfield(MDP, "b") 而不是 "b1",很抱歉造成混淆。

@Roland 的解决方案: 您始终可以使用匿名函数 function(x) if (!is.null(x)) col_norm(x) else NULL。 – 罗兰

最后一行看起来像这样:

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

我不得不用“dim(MDP$B) = matrix(c(2,4))”重新调整列表,但这没关系:))

dim(MDP$B) = 矩阵(c(2,4))

@Roland 的解决方案:使用: MDP$b[] <- lapply(MDP$b, (x) if (!is.null(x)) col_norm(x) else NULL)

colSums函数中有一个na.rm参数:

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

或者如果他们是 NULL,也做:

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

创建一个匿名函数来检查它是否被传递 NULL。您可能还想使用 [<- 而不是 = 来分配到矩阵中并保留其 class 和维度。两者合计:

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