简体   繁体   English

R:如何在LOOP中匹配/合并2个不同维数(nrow / ncol)的矩阵?

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

In addition to my earlier question R: How to match/join 2 matrices of different dimensions (nrow/ncol)? 除了我之前的问题R:如何匹配/合并2个不同维度的矩阵(nrow / ncol)? I need a loop as I have a list of more than 1000 matrices. 我需要一个循环,因为我有1000多个矩阵的列表。 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". 但是,我在将代码实现到matrices “ small_matrix” list的循环中时遇到问题。 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. 我得到一个错误: incorrect number of subscripts on matrix ,这可能是由于我对循环的基本知识中的索引错误所致。 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 . 根据@Jim M.的答案进行新的编辑:对于本示例,您的答案很好用,但是应该像在前一个问题中那样在循环中创建small_matrix(ces)。 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. 正如@Jim M.建议的那样。 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. 然后是@Jim的for循环。 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 谢谢

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. 我将完整的“矩阵”创建为3维数组而不是列表,然后通过遍历数组3d维的相应索引,用较小的矩阵列表填充此数组。

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. 给出具有与每个小矩阵相对应的第三个索引的full_matrix。

, , 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. 编辑:不是像上一个问题那样使用dcast创建data.frames,而是将数据转换为数组( acast ),以便它们可以插入到更大的数组中。

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")
}

I see a couple problems: 我看到几个问题:

  • Use [[ to select an element of a list, eg, small_matrix[[i]] . 使用[[选择列表的元素,例如small_matrix[[i]]
  • full_matrix is initialized to an empty list. full_matrix初始化为空列表。 Hence full_matrix[i] evaluates to list(NULL) 因此, full_matrix[i]计算结果为list(NULL)
  • Your initial code assumes that all row and col names of small_matrix occur in full_matrix . 您的初始代码假定small_matrix所有行名和列名small_matrix出现在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. 确保full_matrix正确初始化。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM