R: How to match/join 2 matrices of different dimensions (nrow/ncol) in a LOOP?

匿名 (未验证) 提交于 2019-12-03 01:26:01

问题:

In addition to my earlier question R: How to match/join 2 matrices of different dimensions (nrow/ncol)? I need a loop as I have a list of more than 1000 matrices. I decide to use the code (from the answers)

full_matrix[rownames(full_matrix) %in% rownames(small_matrix),              colnames(full_matrix) %in% colnames(small_matrix)] <- small_matrix

which worked fine in my case for a single matrix match. However, I have problems implementing this code into a loop for the list of matrices "small_matrix". Here my code:

full_matrix <- list() for(i in 1:length(small_matrix))  {   full_matrix[i][rownames(full_matrix[i]) %in% rownames(small_matrix[i]),                   colnames(full_matrix[i]) %in% colnames(small_matrix[i])] <- small_matrix[i] }

I get the error: incorrect number of subscripts on matrix, which is probably due to a wrong indexing in my basic knowledge of loops. I appreciate any help. Thanks

NEW EDIT according to answer of @Jim M.: Your answer works fine for this example but the small_matrix(ces) should be created as well in a loop like in this former question. Here you find the code example:

library(abind)  a = c("A", "B", "C", "D", "E", "F") full_matrix = array(dim=c(6,6,2)) dimnames(full_matrix) <- list(levels(as.factor(a)), levels(as.factor(a)),                                c("mat1","mat2"))

as @Jim M. advises. And here the new code:

##### new part for small matrix df_import <- data.frame(OC = c("A", "A", "B", "B", "C", "C", "D", "D"),                         TC = c("Z", "Z", "Y", "Y", "X", "X", "W", "W"),                         Value = c(1,2,3,4,5,6,7,8),                         Year = c(2010,2011)) Import_Year <- split(df_import, df_import$Year)  library(reshape2) small_matrix <- list() for(i in 1:length(unique(Import_Year)))  {   small_matrix[[length(small_matrix)+1]] <- dcast(OC ~ TC, data =Import_Year[[i]], value.var = "Value") } small_matrix ##### end new part

and than further the for-loop of @Jim. M:

for(i in seq_along(small_matrix_list)){   afill(full_matrix[, , i], local= TRUE ) <- small_matrix[[i]]    }

However, I get the following error message:

Error in `afill<-.default`(`*tmp*`, local = TRUE, value = list(OC = 1:4,  :    'x' must have names on dimensions corresponding to those in 'value'

Any ideas? Thanks

回答1:

I would create your full "matrix" as a 3-dimensional array rather than a list, and then fill in this array with a list of smaller matrices by looping through the corresponding index of the 3d dimension of the array.

library(abind)  a = c("A", "B", "C", "D", "E", "F") full_matrix = array(dim=c(6,6,2)) dimnames(full_matrix) <- list(levels(as.factor(a)), levels(as.factor(a)),      c("mat1","mat2"))  small_matrix_1 = matrix(c(2, 4, 3, 1, 5, 7, 3, 1, 6), nrow=3, ncol=3) dimnames(small_matrix_1) <- list(c("B","C","E"), c("A","B","F"))  small_matrix_2 = matrix(c(20, 40, 30, 10, 50, 70, 30, 10, 60), nrow=3, ncol=3) dimnames(small_matrix_2) <- list(c("B","C","E"), c("A","B","F"))  small_matrix_list <- list(small_matrix_1, small_matrix_2)  for(i in seq_along(small_matrix_list)){     afill(full_matrix[, , i], local= TRUE ) <- small_matrix_list[[i]]    }

giving full_matrix with the 3rd index corresponding to each of the small matrices.

, , mat1     A  B  C  D  E  F A NA NA NA NA NA NA B  2  1 NA NA NA  3 C  4  5 NA NA NA  1 D NA NA NA NA NA NA E  3  7 NA NA NA  6 F NA NA NA NA NA NA      , , mat2     A  B  C  D  E  F A NA NA NA NA NA NA B 20 10 NA NA NA 30 C 40 50 NA NA NA 10 D NA NA NA NA NA NA E 30 70 NA NA NA 60 F NA NA NA NA NA NA

Edit: Instead of creating data.frames with dcast as in your previous question, I would cast the data as arrays (acast) so that they can inserted into the larger array.

library(reshape2)  small_matrix <- vector(mode = "list", length = 2) # Pre-allocate space in the list  for (i in seq(Import_Year)){   small_matrix[[i]] <- acast(OC ~ TC, data = Import_Year[[i]], value.var = "Value") }


回答2:

I see a couple problems:

  • Use [[ to select an element of a list, e.g., small_matrix[[i]].
  • full_matrix is initialized to an empty list. Hence full_matrix[i] evaluates to list(NULL)
  • Your initial code assumes that all row and col names of small_matrix occur in full_matrix. If they do, you can simplify the assignment as below(*). (If that's not guaranteed, you'll need to subset both sides by the intersection of the names.)
  • Make sure full_matrix gets initialized properly. You might have a list of matrices too, or one common full matrix in which you replace different sub-blocks.

(*)

full_matrix[rownames(small_matrix), colnames(small_matrix)] <- small_matrix


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!