2015-03-03 12 views
5

Załóżmy, że mam listę matryc:przechowywać 2 najwyższe wartości każdego wiersza w liście macierzy 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 

kod do tworzenia matryc:

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 

I chcesz zachować dwie najwyższe wartości w każdym wierszu i zastąp pozostałe pozostałe komórki w tym samym wierszu wartościami zerowymi.

Jeśli istnieje więcej niż dwie komórki, które mają najwyższą wartość, chcę pozostawić wszystkie te komórki w stanie, w jakim się znajdują (na przykład: 10 10 10 0-> 10 10 10 0, 5 1 9 5 -> 5 0 9 5). Wszystkie pozostałe komórki w rzędzie należy ponownie ustawić na 0.

Wyniki powinny wyglądać następująco:

$`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 

Nie jestem pewien, jak podejść do tego problemu, więc każda pomoc jest bardzo mile widziane!

Odpowiedz

4

Oto jeden sposób:

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 

Działa to przez iteracji po elementach listy (za lapply), traktując każdy z kolei jako przedmiot x, a następnie Iterowanie nad rzędami tym x (z apply(x, 1, ...)) wywołując wiersz y i stosując do niego funkcję.

Funkcja stosowane do rzędu y z listy elementu x jest:

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

która przedstawia dwa najwyżej o wartości elementów rzędu (tail(sort(y), 2)) dane logiczne wektor wskazujący, który z elementów y nie są w tym zestawie (z y < ...), podzbioru elementów wektora y z tego logicznego wektora i przypisuje 0 do tych elementów. Wreszcie zwraca zmodyfikowany y.

+2

Może użyć 'y <', ponieważ będzie on szybszy niż '% w%'? Ponadto prawdopodobnie lepiej będzie działać z liczbami zmiennoprzecinkowymi. +1. – BrodieG

+0

@BrodieG Dobry punkt! Dziękuję Ci. – jbaums

Powiązane problemy