【问题标题】:apply, sapply and lappy return NULLapply、sapply 和 lappy 返回 NULL
【发布时间】:2015-07-07 22:17:34
【问题描述】:

我有一个矩阵:

mat <- matrix(c(0,0,0,0,1,1,1,1,-1,-1,-1,-1), ncol = 4 , nrow = 4)

我应用以下函数过滤掉只有正条目的列,但对于有负条目的列,我得到一个NULL。如何从lapplyapplysapply 的输出中抑制NULLs?

> lapply(as.data.frame(mat), function(x) { if( all(x >= 0) ){return(x)} })
$V1
[1] 0 0 0 0

$V2
[1] 1 1 1 1

$V3
NULL

$V4
[1] 0 0 0 0

> sapply(as.data.frame(mat), function(x) { if( all(x >= 0) ){return(x)} })
$V1
[1] 0 0 0 0

$V2
[1] 1 1 1 1

$V3
NULL

$V4
[1] 0 0 0 0


> apply(mat, 2, function(x){if (all(x >= 0)){return(x)}})
[[1]]
[1] 0 0 0 0

[[2]]
[1] 1 1 1 1

[[3]]
NULL

[[4]]
[1] 0 0 0 0

感谢您的帮助。

【问题讨论】:

    标签: r apply lapply sapply


    【解决方案1】:

    怎么样

    dd <- as.data.frame(mat)
    dd[sapply(dd,function(x) all(x>=0))]
    

    • sapply(...) 返回一个逻辑向量(在本例中为 TRUE TRUE FALSE TRUE),指明列是否具有所有非负值。
    • 当与数据框(不是矩阵)一起使用时,带有逻辑向量的单括号索引将数据框视为一个列表(它是)并创建一个仅包含指定的列表元素。

    或者

    dd[apply(mat>=0,2,all)]
    

    在这种情况下,我们在原始矩阵上使用apply(...,2,...) 来生成逻辑索引向量。

    mat[,apply(mat>=0,2,all)]
    

    在这种情况下,由于我们正在索引一个矩阵,我们使用[,logical_vector] 来选择列。

    【讨论】:

    • 谢谢,但是即使您不在 sapply 前加逗号,它怎么会起作用?
    • mat[,colSums(mat&gt;=0)&gt;0]
    【解决方案2】:

    另一个选择是Filter 你的结果,而Negateing NULLs(如果你想保持列表格式)

    Res <- lapply(as.data.frame(mat), function(x) if(all(x >= 0)) x)
    Filter(Negate(is.null), Res)
    # $V1
    # [1] 0 0 0 0
    # 
    # $V2
    # [1] 1 1 1 1
    # 
    # $V4
    # [1] 0 0 0 0
    

    【讨论】:

    • 或者直接在Filter 开始:Filter(function(x) all(x &gt;= 0), as.data.frame(mat)) 以避免额外的循环(如果需要,可以在末尾使用as.list
    • @eddi 不错,没想到。
    猜你喜欢
    • 2020-11-14
    • 2016-08-30
    • 2013-10-31
    • 2020-08-17
    • 1970-01-01
    • 2017-07-16
    • 2016-06-28
    • 1970-01-01
    • 2019-09-08
    相关资源
    最近更新 更多