2015-04-28 31 views
10

powrót Mam matrycy:zastosować, sapply i lappy NULL

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

i zastosować następujące funkcje odfiltrować kolumn z tylko pozytywne wpisy, ale dla kolumn, które mają negatywne wpisy dostaję NULL . Jak mogę wyłączyć NULL s z wyjścia lapply, apply i 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 

Dzięki za pomoc.

Odpowiedz

8

Jak o

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

?

  • sapply(...) zwraca wektor logiczny (w tym przypadku TRUE TRUE FALSE TRUE), który stwierdza, czy kolumny mają wszystkie wartości nieujemne.
  • w przypadku użycia z ramką danych (bez matrycy), indeksowanie pojedynczych nawiasów za pomocą wektora logicznego traktuje ramkę danych jako listę (która jest) i tworzy listę zawierającą tylko określone elementy.

Lub alternatywnie

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

W tym przypadku używamy apply(...,2,...) na oryginalnej matrycy do generowania logicznego indeksowania wektor.

lub

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

W tym przypadku, ponieważ mamy do indeksowania macierzy używamy [,logical_vector] aby wybrać kolumny.

+1

dzięki, ale jak to się stało, że działa nawet wtedy, gdy nie umieścić przecinek przed sapply? – Cauchy

+0

'mat [, colSums (mat> = 0)> 0]' również – thelatemail

7

Inną opcją jest Filter Twój wynik podczas Negate ing NULL s (jeśli chcesz zachować go w formacie listy)

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

lub po prostu zrób to w 'Filter' na początek:' Filter (function (x) all (x> = 0), as.data.frame (mat)) ', aby uniknąć dodatkowej pętli (można użyć' as.list' na końcu, jeśli to konieczne) – eddi

+0

@eddi ładny, nie myślałem o tym. –