【问题标题】:R: How to match/join 2 matrices of different dimensions (nrow/ncol) in a LOOP?R:如何在一个循环中匹配/连接 2 个不同维度的矩阵(nrow/ncol)?
【发布时间】:2015-12-23 17:02:19
【问题描述】:

除了我之前的问题R: How to match/join 2 matrices of different dimensions (nrow/ncol)?,我还需要一个循环,因为我有一个包含 1000 多个矩阵的列表。我决定使用代码(来自答案)

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

在我的情况下,对于单个矩阵匹配来说效果很好。但是,我在将此代码实现到listmatrices“small_matrix”的循环中时遇到问题。这是我的代码:

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]
}

我收到错误:incorrect number of subscripts on matrix,这可能是由于我对循环的基本知识中的索引错误。我很感激任何帮助。谢谢

根据@Jim M. 的回答进行新编辑: 您的答案适用于此示例,但 small_matrix(ces) 也应该像以前的question 一样在循环中创建。在这里你可以找到代码示例:

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

正如@Jim M. 建议的那样。这里是新代码:

##### 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

还有@Jim 的 for 循环。男:

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

但是,我收到以下错误消息:

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

有什么想法吗?谢谢

【问题讨论】:

  • 每个较小矩阵的完整矩阵是否相同,是否需要列表作为输出?

标签: r matrix


【解决方案1】:

我发现了几个问题:

  • 使用[[ 选择列表中的一个元素,例如small_matrix[[i]]
  • full_matrix 被初始化为一个空列表。因此full_matrix[i] 计算为list(NULL)
  • 您的初始代码假定small_matrix 的所有行和列名称都出现在full_matrix 中。如果他们这样做,您可以将分配简化如下(*)。 (如果不能保证,您需要通过名称的交集对两边进行子集化。)
  • 确保full_matrix 被正确初始化。您可能还有一个矩阵列表,或者一个常见的完整矩阵,您可以在其中替换不同的子块。

(*)

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

【讨论】:

    【解决方案2】:

    我会将您的完整“矩阵”创建为 3 维数组而不是列表,然后通过循环遍历数组 3 维的相应索引,用更小的矩阵列表填充此数组。

    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]]   
    }
    

    给予 全矩阵 第三个索引对应每个小矩阵。

    , , 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
    

    编辑:我不会像您之前的问题那样使用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")
    }
    

    【讨论】:

    • 感谢您的回答,这对于本示例来说效果很好,但我的真实数据仍然存在问题,请参阅编辑。主意?谢谢
    • @N.Varela:我已经编辑了对您问题的回复,以解决如何在循环中转换数组。
    • 非常感谢您的编辑。 acast 工作正常
    猜你喜欢
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2015-10-09
    • 2017-12-01
    • 1970-01-01
    • 2020-01-19
    相关资源
    最近更新 更多