Reputation: 1747
I have a matrix:
mat <- matrix(c(0,0,0,0,1,1,1,1,-1,-1,-1,-1), ncol = 4 , nrow = 4)
and I apply the following functions to filter out the columns with only positive entries, but for the columns that have negative entries I get a NULL
. How can I suppress the NULL
s from the output of lapply
, apply
and sapply
?
> 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
Thanks for any help.
Upvotes: 11
Views: 3239
Reputation: 226097
How about
dd <- as.data.frame(mat)
dd[sapply(dd,function(x) all(x>=0))]
?
sapply(...)
returns a logical vector (in this case TRUE TRUE FALSE TRUE
) that states whether the columns have all non-negative values.Or alternatively
dd[apply(mat>=0,2,all)]
In this case we use apply(...,2,...)
on the original matrix to generate the logical indexing vector.
or
mat[,apply(mat>=0,2,all)]
In this case since we are indexing a matrix we use [,logical_vector]
to select columns.
Upvotes: 8
Reputation: 92282
Another option is to Filter
your result while Negate
ing NULL
s (if you want to keep it in a list format)
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
Upvotes: 8