【问题标题】:Creating a full diallel using R使用 R 创建一个完整的拨号盘
【发布时间】:2012-09-18 10:13:08
【问题描述】:

我对 R 比较陌生,如果这个问题太基本,请原谅。 我想知道是否有一种使用 R 创建完整拨号盘的好方法和快速方法?

我有一个看起来像这样的矩阵:

          M1 M2 M3
   Line1  A  B  A
   Line2  A  A  B
   Line3  B  A  A

我想从这个矩阵中创建以下数据框:

 X       Y       M1   M2  M3
 Line1   Line1   AA   BB  AA
 Line1   Line2   AA   BA  AB
 Line1   Line3   AB   BA  AA
 Line2   Line1   AA   AB  BA
 Line2   Line2   AA   AA  BB
 Line2   Line3   AB   AA  BA
 Line3  Line1    BA   AB  AA
 Line3  Line2    BA   AA  AB
 Line3  Line3    BB   AA  AA

我认为这可以通过创建几个嵌套循环并使用粘贴来组合 A 和 B 字母代码来实现。但可能有更好和更多“R-like”选项(使用cbind()?)。

【问题讨论】:

    标签: r matrix dataframe rbind


    【解决方案1】:

    一种方法是考虑构成所需输出的每一行的数据行的索引。使用您的数据:

    mat <- matrix(c("A","B","A",
                    "A","A","B",
                    "B","A","A"), ncol = 3, byrow = TRUE)
    

    我使用expand.grid() 创建这些索引。输出的第一行由mat 的第1 行与mat 的第1 行串联形成,依此类推。这些指数产生如下

    > ind <- expand.grid(r1 = 1:3, r2 = 1:3)
    > ind
      r1 r2
    1  1  1
    2  2  1
    3  3  1
    4  1  2
    5  2  2
    6  3  2
    7  1  3
    8  2  3
    9  3  3
    

    请注意,要获得您的输出显示的内容,我们需要先取列r2,然后再取r1,而不是反过来。

    现在我只是用ind 的第二列和ind 的第一列索引mat,并将其提供给paste0(),输出是一个向量,因此我们需要将其重塑为矩阵。

    > matrix(paste0(mat[ind[,2], ], mat[ind[,1], ]), ncol = 3)
          [,1] [,2] [,3]
     [1,] "AA" "BB" "AA"
     [2,] "AA" "BA" "AB"
     [3,] "AB" "BA" "AA"
     [4,] "AA" "AB" "BA"
     [5,] "AA" "AA" "BB"
     [6,] "AB" "AA" "BA"
     [7,] "BA" "AB" "AA"
     [8,] "BA" "AA" "AB"
     [9,] "BB" "AA" "AA"
    

    paste0() 步骤返回粘贴字符串的向量:

    > paste0(mat[ind[,2], ], mat[ind[,1], ])
     [1] "AA" "AA" "AB" "AA" "AA" "AB" "BA" "BA" "BB" "BB" "BA" "BA" "AB" "AA" "AA"
    [16] "AB" "AA" "AA" "AA" "AB" "AA" "BA" "BB" "BA" "AA" "AB" "AA"
    

    关于为什么上面显示的矩阵重组有效的诀窍是注意paste0() 的输出中的条目是列优先顺序,因为索引ind 是如何形成的。本质上,传递给paste0() 的两个参数是:

    > mat[ind[,2], ]
          [,1] [,2] [,3]
     [1,] "A"  "B"  "A" 
     [2,] "A"  "B"  "A" 
     [3,] "A"  "B"  "A" 
     [4,] "A"  "A"  "B" 
     [5,] "A"  "A"  "B" 
     [6,] "A"  "A"  "B" 
     [7,] "B"  "A"  "A" 
     [8,] "B"  "A"  "A" 
     [9,] "B"  "A"  "A" 
    > mat[ind[,1], ]
          [,1] [,2] [,3]
     [1,] "A"  "B"  "A" 
     [2,] "A"  "A"  "B" 
     [3,] "B"  "A"  "A" 
     [4,] "A"  "B"  "A" 
     [5,] "A"  "A"  "B" 
     [6,] "B"  "A"  "A" 
     [7,] "A"  "B"  "A" 
     [8,] "A"  "A"  "B" 
     [9,] "B"  "A"  "A"
    

    R 将每个都视为一个向量,因此输出是一个向量,但由于 R 按列存储矩阵,我们也用列粘贴的字符串填充输出矩阵。

    【讨论】:

      【解决方案2】:

      你可能不需要几个循环来获得你的输出,这里有一个建议:

      首先,让我们生成您的样本矩阵:

      M <- matrix(c("A","B","A","A","A","B","B","A","A"), ncol = 3, byrow = TRUE)
      rownames(M) <- c("Line1","Line2","Line3")
      colnames(M) <- c("M1","M2","M3")
      

      使用expand.grid() 可以轻松生成向量中项目之间的所有可能对:

      d <- expand.grid(rownames(M), rownames(M))
      

      在所需的输出中生成列 X 和 Y:

         Var1  Var2
      1 Line1 Line1
      2 Line2 Line1
      3 Line3 Line1
      4 Line1 Line2
      5 Line2 Line2
      6 Line3 Line2
      7 Line1 Line3
      8 Line2 Line3
      9 Line3 Line3
      

      然后,您可以做的是 apply() 将相应的 M1、M2、M3 值粘贴在一起的每一行的函数:

      apply(d, 1, function(x) { paste(M[x[1],], paste(M[x[2],]), sep="")} )
      

      它将生成正确的组合,但格式不正确(目前):

           [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
      [1,] "AA" "AA" "BA" "AA" "AA" "BA" "AB" "AB" "BB"
      [2,] "BB" "AB" "AB" "BA" "AA" "AA" "BA" "AA" "AA"
      [3,] "AA" "BA" "AA" "AB" "BB" "AB" "AA" "BA" "AA"
      

      要向正确的方向翻转矩阵,您只需将其转置即可。

      从那里,您可以一次将所有内容包装到一个数据框中:

      df <- data.frame( d, t(apply(d, 1, function(x) { paste(M[x[1],], paste(M[x[2],]), sep="")} ))
      colnames(df) <- c("X","Y","M1","M2", "M3")
      

      就在这里。

      为了更高效,你终于可以编写一个小函数来提交任何 M 矩阵。

      get.it <- function(M){ 
          d <- expand.grid(rownames(M), rownames(M))
          e <- t(apply(d, 1, function(x) { paste(M[x[1],], paste(M[x[2],]), sep="")} ))
          output<- data.frame( d, e)
          colnames(output) <- c("X","Y","M1","M2","M3")
      return(output)
      }
      

      get.it(M) 应该可以工作!

      【讨论】:

      • 请注意,如果您有超过 3 列,列名将成为问题,但原则应该与任何列/项目集相同(例如 A、B、C、D... )。
      • 哇,你们俩都很棒。我自己永远无法找到如此有效的方法。他们俩都像魅力一样工作。我将使用它们为 70x400 重建完整的拨号盘。非常感谢你的帮助!罗尼
      猜你喜欢
      • 1970-01-01
      • 2018-10-11
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多