【问题标题】:Extend matrix or data frame to be quadratic having same row and column names将矩阵或数据框扩展为具有相同行名和列名的二次方
【发布时间】:2020-12-10 21:54:06
【问题描述】:

如何轻松地将矩阵或数据框扩展为二次方,即具有相同的行名和列名。在缺少值的地方,我只希望它们为零。

可重现的例子:

cols<-c("A","B","D","F")
rows<-c("A","B","C", "E", "F")
data<-matrix(runif(20),nrow = length(rows), ncol = length(cols))
colnames(data)<-cols
rownames(data)<-rows

所以目标是有一个 6x6 矩阵,列/行名从“A”到“F”,值如 data 中的值,缺失的地方用零填充。

感谢您的任何想法!

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    这是另一个使用嵌套 for 循环的基本 R 选项

    nm <- sort(union(colnames(data),row.names(data)))
    res <- `dimnames<-`(matrix(0,nrow = length(nm),ncol = length(nm)),replicate(2,nm,simplify = FALSE))
    for (i in rows) {
      for (j in cols) {
        res[i,j] <- data[i,j]
      }
    }
    

    给了

    > res
               A         B C         D E          F
    A 0.02778712 0.1386282 0 0.2263808 0 0.68144251
    B 0.52731078 0.3214921 0 0.1314165 0 0.09916910
    C 0.88031907 0.1548316 0 0.9815635 0 0.11890256
    D 0.00000000 0.0000000 0 0.0000000 0 0.00000000
    E 0.37306337 0.1322282 0 0.3270137 0 0.05043966
    F 0.04795913 0.2213059 0 0.5069395 0 0.92925392
    

    【讨论】:

    • 你会认为应该有比我们的任何一种循环解决方案 Thomas 更好的方法,但我就是看不到。
    • @AllanCameron 好点!我看到了您的努力,使用expand.grid 提供了很好的解决方案,为您的回答点赞!
    【解决方案2】:

    这似乎有点啰嗦,但这里有一个小函数可以泛化到任何具有行名和列名的矩阵:

    make_quadratic <- function(data)
    {
      names <- sort(unique(c(colnames(data), rownames(data))))
      size  <- length(names)
      
     `colnames<-`(`rownames<-`(apply(apply(data, 1, 
      function(x) replace(numeric(size), names %in% colnames(data), x)), 1, 
      function(x) replace(numeric(size), names %in% rownames(data), x)),
      names), names)
    }
    

    所以,例如:

    make_quadratic(data)
    #>           A         B C         D E          F
    #> A 0.1033626 0.4390343 0 0.9368352 0 0.47888726
    #> B 0.3897981 0.1563756 0 0.3148652 0 0.79636682
    #> C 0.6780338 0.4937433 0 0.1325104 0 0.10266721
    #> D 0.0000000 0.0000000 0 0.0000000 0 0.00000000
    #> E 0.7667374 0.1198529 0 0.8930371 0 0.35349412
    #> F 0.1467854 0.4649394 0 0.5838215 0 0.05615008
    

    编辑

    不包括循环的替代答案:

    i <- as.matrix(expand.grid(row = which(LETTERS[1:6] %in% rownames(data)),
                               col = which(LETTERS[1:6] %in% colnames(data))))
    
    result <- matrix(0, nrow = 6, ncol = 6, 
                     dimnames = list(LETTERS[1:6], LETTERS[1:6]))
    
    result[i] <- data
    
    result
    #>           A         B C         D E          F
    #> A 0.1033626 0.4390343 0 0.9368352 0 0.47888726
    #> B 0.3897981 0.1563756 0 0.3148652 0 0.79636682
    #> C 0.6780338 0.4937433 0 0.1325104 0 0.10266721
    #> D 0.0000000 0.0000000 0 0.0000000 0 0.00000000
    #> E 0.7667374 0.1198529 0 0.8930371 0 0.35349412
    #> F 0.1467854 0.4649394 0 0.5838215 0 0.05615008
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      相关资源
      最近更新 更多