2015-01-27 6 views
6

Supponiamo di avere due elenchi che includono più matrici. Il primo elenco comprende matrici con dimensioni diverse da matrice a matrice:Matrici di unione da due elenchi in R

codice per creare list1:

d<-c(0,1,0,1) 
e<-c(1,0,0,0) 
f<-c(0,0,0,0) 
g<-c(1,0,0,0) 
cn<-c(1,2,3,4) 
p<-data.frame(d,e,f,g) 
dimnames(p)<-list(cn,cn) 

d<-c(0,1,0,1,0) 
e<-c(1,0,0,0,0) 
f<-c(0,0,0,0,0) 
g<-c(1,0,0,0,1) 
h<-c(0,0,0,1,0) 
cn<-c(1,2,3,4,5) 
q<-data.frame(d,e,f,g,h) 
dimnames(q)<-list(cn,cn) 

list1<-list(p,q) 
names(list1)<-1990:1991 

List1:

list1 

$`1990` 
    1 2 3 4 
1 0 1 0 1 
2 1 0 0 0 
3 0 0 0 0 
4 1 0 0 0 

$`1991` 
    1 2 3 4 5 
1 0 1 0 1 0 
2 1 0 0 0 0 
3 0 0 0 0 0 
4 1 0 0 0 1 
5 0 0 0 1 0 

Il secondo elenco comprende matrici che hanno sempre le stesse dimensioni e includere tutti i casi che si verificano mai nelle matrici di List1 (6,7 si verificherebbe in matrici aggiuntive nella lista1).

codice per produrre lista2:

o<-matrix(NA,nrow=7,ncol=7) 
dimnames(o)<-list(1:7, 1:7) 
list2<-list(o,o) 
names(list2)<-1990:1991 

Lista2:

list2 
$`1990` 
    1 2 3 4 5 6 7 
1 NA NA NA NA NA NA NA 
2 NA NA NA NA NA NA NA 
3 NA NA NA NA NA NA NA 
4 NA NA NA NA NA NA NA 
5 NA NA NA NA NA NA NA 
6 NA NA NA NA NA NA NA 
7 NA NA NA NA NA NA NA 

$`1991` 
    1 2 3 4 5 6 7 
1 NA NA NA NA NA NA NA 
2 NA NA NA NA NA NA NA 
3 NA NA NA NA NA NA NA 
4 NA NA NA NA NA NA NA 
5 NA NA NA NA NA NA NA 
6 NA NA NA NA NA NA NA 
7 NA NA NA NA NA NA NA 

Quello che vorrei fare è di sostituire il NA in lista2 con, se disponibili, i valori della relativa matrice da lista1, in modo che il risultato è simile al seguente:

$`1990` 
    1 2 3 4 5 6 7 
1 0 1 0 1 NA NA NA 
2 1 0 0 0 NA NA NA 
3 0 0 0 0 NA NA NA 
4 1 0 0 0 NA NA NA 
5 NA NA NA NA NA NA NA 
6 NA NA NA NA NA NA NA 
7 NA NA NA NA NA NA NA 

$`1991` 
    1 2 3 4 5 6 7 
1 0 1 0 1 0 NA NA 
2 1 0 0 0 0 NA NA 
3 0 0 0 0 0 NA NA 
4 1 0 0 0 1 NA NA 
5 0 0 0 1 0 NA NA 
6 NA NA NA NA NA NA NA 
7 NA NA NA NA NA NA NA 

suppongo che ci sia un modo per fare questo da noi il comando di fusione. Tuttavia, non ho ancora trovato alcuna soluzione, quindi qualsiasi input è benvenuto!

risposta

5

buona opportunità di utilizzare Map (bisogna data.frame nel primo elenco, convertirli in matrix prima!):

lst1 = lapply(list1, data.matrix) 

> Map(function(m,p) {m[1:nrow(p),1:ncol(p)]=p;m}, list2, lst1) 
$`1990` 
    1 2 3 4 5 6 7 
1 0 1 0 1 NA NA NA 
2 1 0 0 0 NA NA NA 
3 0 0 0 0 NA NA NA 
4 1 0 0 0 NA NA NA 
5 NA NA NA NA NA NA NA 
6 NA NA NA NA NA NA NA 
7 NA NA NA NA NA NA NA 

$`1991` 
    1 2 3 4 5 6 7 
1 0 1 0 1 0 NA NA 
2 1 0 0 0 0 NA NA 
3 0 0 0 0 0 NA NA 
4 1 0 0 0 1 NA NA 
5 0 0 0 1 0 NA NA 
6 NA NA NA NA NA NA NA 
7 NA NA NA NA NA NA NA 

Come da @akrun suggerimento, una soluzione più generalista:

f = function(A,B) 
{ 
    A[row.names(A) %in% row.names(B), colnames(A) %in% colnames(B)]=B 
    A 
} 

Map(f, list2, lapply(list1, data.matrix)) 
+2

invece di 1: nrow, 1: ncol, un approccio più generale sarebbe quello di far corrispondere row.names/colnames tra i dataset corrispondenti, specialmente quando i nomi non sono ordinati. – akrun

+0

buona idea! Ho menzionato il tuo suggerimento! –

+0

Mi sono appena reso conto che ho alcune matrici in list1 che contengono effettivamente casi non inclusi in list2. Le matrici in list1 talvolta hanno anche dimensioni maggiori rispetto alle matrici in list2. In questi casi, il codice non funziona. Voglio mantenere la dimensione delle mie matrici standard. Come avrei bisogno di cambiare la funzione, in modo che funzioni anche in questa situazione? – jsts