2015-03-03 6 views
5

nehme ich eine Liste von Matrizen haben:Halten Sie die 2 höchsten Werte jeder Zeile in einer Liste von Matrizen r

$`2010` 
    1 2 3 4 
1 0 3 5 6 
2 5 1 9 5 
3 0 0 0 0 
4 10 10 10 0 

$`2011` 
    1 2 3 4 
1 0 2 3 6 
2 5 0 3 1 
3 2 4 0 1 
4 2 1 2 1 

-Code die Matrizen zu erstellen:

cntry<-c(1,2,3,4) 
a<-c(0,5,0,10) 
b<-c(3,1,0,10) 
c<-c(5,9,0,10) 
d<-c(6,5,0,0) 
k<-data.frame(a,b,c,d) 
k<-as.matrix(k) 
dimnames(k)<-list(cntry,cntry) 

e<-c(0,5,2,2) 
f<-c(2,0,4,1) 
g<-c(3,3,0,2) 
h<-c(6,1,1,1) 
l<-data.frame(e,f,g,h) 
l<-as.matrix(l) 
dimnames(l)<-list(cntry,cntry) 

list<-list(k,l) 
names(list)<-2010:2011 

Ich möchte das halten zwei höchste Werte in jeder Zeile, und ersetzen Sie die verbleibenden kleineren Werte der anderen Zellen in der gleichen Zeile mit Nullen.

Wenn es mehr als zwei Zellen gibt, die den höchsten Wert haben, möchte ich alle diese Zellen so belassen wie sie sind (zum Beispiel: 10 10 10 0 -> 10 10 10 0, 5 1 9 5 -> 5 0 9 5). Alle anderen Zellen der Zeile sollten wieder auf 0 gesetzt werden.

Die Ergebnisse sollen wie folgt aussehen:

$`2010` 
    1 2 3 4 
1 0 0 5 6 
2 5 0 9 5 
3 0 0 0 0 
4 10 10 10 0 

$`2011` 
    1 2 3 4 
1 0 0 3 6 
2 5 0 3 0 
3 2 4 0 0 
4 2 0 2 0 

Ich bin nicht sicher, wie dieses Problem zu nähern, so ist jede Hilfe sehr willkommen!

Antwort

4

Hier ist ein Ansatz:

lapply(list, function(x) { 
    t(apply(x, 1, function(y) { 
    y[!y %in% tail(sort(y), 2)] <- 0 
    y 
    })) 
}) 

## $`2010` 
## 1 2 3 4 
## 1 0 0 5 6 
## 2 5 0 9 5 
## 3 0 0 0 0 
## 4 10 10 10 0 
## 
## $`2011` 
## 1 2 3 4 
## 1 0 0 3 6 
## 2 5 0 3 0 
## 3 2 4 0 0 
## 4 2 0 2 0 

Dies funktioniert, indem über Elemente der Liste iterieren (mit lapply), die jeweils als das Objekt wiederum Behandlung x und dann Iterieren über die Reihen dieser x (mit apply(x, 1, ...)) Rufen Sie die Zeile y auf und wenden Sie eine Funktion darauf an.

Die Funktion zur Reihe y von Listenelement angelegt x ist:

function(y) { 
    y[y < tail(sort(y), 2)] <- 0 
    y 
} 

, die die zwei höchstwertigen Elemente der Reihe (tail(sort(y), 2)) identifiziert, eine logische Vektor zurück y die der Elemente der Anzeige sind nicht in diesem Satz (mit y < ...), unterteilen die Elemente des Vektors y mit diesem logischen Vektor und weisen diesen Elementen 0 zu. Schließlich gibt es die modifizierte y zurück.

+2

Vielleicht verwenden Sie 'y <', da es schneller als '% in%' ist? Auch wird es wahrscheinlich besser mit Gleitkommazahlen funktionieren. +1. – BrodieG

+0

@ Brodieg Guter Punkt! Vielen Dank. – jbaums

Verwandte Themen