2015-01-27 63 views
6

Giả sử tôi có hai danh sách bao gồm nhiều ma trận. Danh sách đầu tiên bao gồm các ma trận với kích thước khác với ma trận để ma trận:Hợp nhất ma trận từ hai danh sách trong R

Mã để tạo 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 

danh sách thứ hai bao gồm các ma trận mà luôn luôn có kích thước tương tự và bao gồm tất cả các trường hợp xảy ra trong ma trận List1 (6,7 sẽ xảy ra trong các ma trận bổ sung trong danh sách1).

Mã để sản xuất List2:

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

List2:

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 

Những gì tôi muốn làm là thay thế của NA trong List2 với, nếu có, các giá trị từ các ma trận tương ứng từ list1, để kết quả trông giống như sau:

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

Tôi cho rằng có cách để làm điều này bởi chúng tôi ing lệnh merge. Tuy nhiên, tôi chưa tìm ra giải pháp nào, vì vậy mọi đầu vào đều được chào đón rất nhiều!

Trả lời

5

tốt cơ hội sử dụng Map (bạn có data.frame trong danh sách đầu tiên của bạn, chuyển đổi chúng trong matrix đầu tiên!):

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 

Theo @akrun gợi ý, một giải pháp chung chung hơn:

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

thay vì 1: nrow, 1: ncol, một cách tiếp cận tổng quát hơn sẽ phù hợp với row.names/colnames giữa các tập dữ liệu tương ứng, đặc biệt khi các tên không được đặt hàng. – akrun

+0

ý tưởng hay! Tôi đã đề cập đến đề xuất của bạn! –

+0

Tôi vừa mới nhận ra rằng tôi có một số ma trận trong danh sách1 thực sự chứa các trường hợp không có trong danh sách2. Các ma trận trong list1 đôi khi cũng có kích thước lớn hơn các ma trận trong list2. Trong những trường hợp này, mã không hoạt động. Tôi muốn giữ kích thước của ma trận chuẩn của mình. Làm thế nào tôi cần phải thay đổi chức năng, để nó cũng hoạt động trong tình huống này? – jsts

Các vấn đề liên quan