2015-04-28 9 views
10

Ich habe eine Matrix:gelten, sapply und lappy Rückkehr NULL

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

und ich gelten die folgenden Funktionen die Spalten mit nur positive Einträge, um herauszufiltern, aber für die Spalten, die negative Einträge haben erhalte ich eine NULL . Wie kann ich die s von der Ausgabe lapply, apply und sapply unterdrücken?

> 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 

Danke für jede Hilfe.

Antwort

8

Wie wäre es

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

?

  • sapply(...) gibt einen logischen Vektor (in diesem Fall TRUE TRUE FALSE TRUE), die besagt, ob die Spalten alle nicht-negative Werte haben.
  • Bei der Verwendung mit einem Datenrahmen (keine Matrix) behandelt Indexierung mit einem Klammer mit einem logischen Vektor den Datenrahmen als eine Liste (was es ist) und erstellt eine Liste, die nur die angegebenen Elemente enthält.

Oder alternativ

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

In diesem Fall verwenden wir apply(...,2,...) auf der ursprünglichen Matrix der logischen Indizierung Vektor zu erzeugen.

oder

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

In diesem Fall, da wir eine Matrix indizieren verwenden wir [,logical_vector] Spalten auswählen.

+1

Dank an (wenn Sie es in einem Listenformat behalten wollen), aber wie kommt es, dass auch funktioniert, wenn Sie nicht ein Komma setzen Sie vor dem Sapply? – Cauchy

+0

'mat [, colSums (mat> = 0)> 0]' auch – thelatemail

7

Eine weitere Möglichkeit ist Filter Ihr Ergebnis während NegateNULL s ing

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

oder einfach in 'Filter' anfangen:' Filter (function (x) all (x> = 0), as.dat.frame (mat)) 'um eine extra Schleife zu vermeiden (kann am Ende' as.list' am Ende benutzen) – eddi

+0

@eddi netter, dachte nicht daran. –