apply、sapply和lapply返回NULL

11

我有一个矩阵:

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

我使用以下函数筛选仅包含正数条目的列,但对于具有负条目的列,我会得到一个NULL。如何从lapplyapplysapply的输出中抑制NULL

> 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

感谢任何帮助。

2个回答

8
如何?
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]”来选择列。

1
谢谢,但是为什么在sapply之前不加逗号也能正常工作呢? - Cauchy
mat[,colSums(mat>=0)>0] 也。 - thelatemail

8
另一种选择是在保持列表格式的同时,通过过滤结果并否定空值来实现。
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

4
可以直接在Filter函数中实现:Filter(function(x) all(x >= 0), as.data.frame(mat)),这样可以避免额外的循环(如果必要,可以在最后使用as.list函数)。请注意,翻译过程中不改变原意,也不提供任何解释或其他信息。 - eddi
@eddi 不错,我没想到。 - David Arenburg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接