代码之家  ›  专栏  ›  技术社区  ›  gvdr

矩阵中的字符串操作:一个维度问题

  •  0
  • gvdr  · 技术社区  · 13 年前

    我试图定义一个函数来操作R中的字符串矩阵。

    {+,*}矩阵乘法

    两个平方矩阵的{+,*}-乘积 A. B 维数为n的是一个矩阵 C 由以下元素定义: C i、 j =总和 k=1,。。。,n A. i、 k * B k、 j .

    例如,考虑矩阵 M <- matrix(c(a,b,0,0,c,d,0,0,e),3,3) 那么M乘以M M <- matrix(c(a^2,a*b+b*c,b*d,0,c^2,c*d+d*e,0,0,e^2),3,3) .

    {c(,),paste0(,)}矩阵乘法

    我想实现的这个运算的规则与前面所说的乘法相同,有一个基本的突变,即和应该是串联的,乘积应该是粘贴的。换句话说,在前面的公式中,我们发现 a+b ,现在输出应该是“c(a,b)”,当我们发现 a*b ,现在我们应该将其解读为 paste0(a,b) .

    必须重新描述一些常见的属性,即分配属性和0元素属性。因此,如果 a <- c("q",0,"w") b <- c("e") 然后 a*b <- c("qe",0,"we") (我们应该自由地忘记0元素,删除它,因为它不会影响计算。

    此外,我们正在乘以等维矩阵,因此每个元素 C i、 j =总和 k=1,。。。,n A. i、 k * B k、 j 现在读作 c("A[i,1]B[1,j]",...,"A[i,n]B[n,j]") .

    出于语义的考虑,让我们考虑 B 总是一个 易于理解的 矩阵,意味着它的每个元素都是原子字符串,而不是字符串的串联(泛化是后续步骤)。

    让我们举一个例子。允许 A <- matrix(c("a","b",0,0,"c","d",0,0,"e"),3,3) 然后 mult(A,A) = matrix(c("aa",c("ab","bc"),"bd",0,"cc",c("cd","de"),0,0,"ee"),3,3) mult(mult(A,A),A) = matrix(c("aaa",c("aab","abc","bcc"),c("abd","bcd","bde"),0,"ccc",c("ccd","cde","dee"),0,0,"eee"),3,3) .

    部分(无效)实施

    考虑一对nxn矩阵作为输入 M , N 无论是0还是字符串数组c( s 1. , s 2. ,...) 像 i、 j 元素。作为输出,我想要一个矩阵 MN=M x N 其中乘法是以与符号乘法类似的方式定义的:

    i、 j =0如果 M i、 ,。 N j 为0
    i、 j =粘贴( M i、 ,。 , N j )否则(使用 分配的 的财产 paste() )

    我给出了基数的定义(错误,没有正确检查零) 行/列粘贴 作为

    MijPaste <- function(Row,Col){
      if(Col[1]=="0"){
        Mij <- 0
      } else if(Row[1]=="0"){
          Mij <- 0
        } else
          Mij <- paste(Row,Col,sep="")
      return(Mij)
    }
    

    我还没能从这一步到乘法函数的正确定义,因为我想插入矩阵中的元素Mij的维数不正确。因此我得到了 number of items to replace is not a multiple of replacement length 错误我目前的实施方式是:

    # define the dimension of the matrix, here for example 3
    dim <- 3
    # define the Multiplication function as an iteration of the MijPaste function
    Mult <- function(M1,M2){
        #allocate a matrix of dimension nxn
        M <-  matrix(0,dim,dim)
        #for each element i,j define it as the MijPaste of row i column j
          for(i in 1:dim){
          for(j in 1:dim){
            stringi <- M1[i,]
            stringj <- M2[,j]
            M[i,j] <- MijPaste(stringi,stringj)
          }
        }
      return(M)
    }
    

    代码不起作用。我可能会将矩阵更改为多维数组,但我希望输出可以用作进一步乘法的矩阵(例如定义(MxN)xC)。

    我该怎么办?

    非常感谢。

    附言:您可以使用一个简单的示例矩阵来测试代码

    Matr <- matrix(c("11","12","13","21","22","23","31","32","33"),dim,dim)
    

    和跑步

    Mult(Matr,Matr)
    
    2 回复  |  直到 13 年前
        1
  •  0
  •   Ferdinand.kraft    13 年前

    您可以使用 paste 如果手动设置维度,则直接使用矩阵:

    MN <- matrix(paste(M, N, sep=""), nrow=nrow(M), ncol=ncol(M))
    

    现在过滤零并替换:

    MN[(M==0) | (N==0)] <- 0
    

    编辑:上面显示的逐点产品不是OP想要的。

    正如我在评论中所说,你可以通过添加 collapse="" 到您的第一个功能。我得到以下结果:

    > M <- matrix(LETTERS[1:9],3,3)
    > N <- matrix(LETTERS[10:18],3,3)
    
    > M
         [,1] [,2] [,3]
    [1,] "A"  "D"  "G" 
    [2,] "B"  "E"  "H" 
    [3,] "C"  "F"  "I" 
    > N
         [,1] [,2] [,3]
    [1,] "J"  "M"  "P" 
    [2,] "K"  "N"  "Q" 
    [3,] "L"  "O"  "R" 
    
    > Mult(M,N)
         [,1]     [,2]     [,3]    
    [1,] "AJDKGL" "AMDNGO" "APDQGR"
    [2,] "BJEKHL" "BMENHO" "BPEQHR"
    [3,] "CJFKIL" "CMFNIO" "CPFQIR"
    

    正如您所看到的,您的函数与矩阵中的元素相匹配 M N 之前 粘贴。

    如果要将每个矩阵的元素保持在一起,可以使用以下两行:

    > coll <- function(x)paste(x,collapse="")
    > outer(apply(M,1,coll),apply(N,2,coll),paste0)
         [,1]     [,2]     [,3]    
    [1,] "ADGJKL" "ADGMNO" "ADGPQR"
    [2,] "BEHJKL" "BEHMNO" "BEHPQR"
    [3,] "CFIJKL" "CFIMNO" "CFIPQR"
    

    当然,您必须手动在此之后插入零。

        2
  •  0
  •   Community Mohan Dere    5 年前
    pmat <- function(m1, m2) matrix(
              ifelse(m1=="0"|m2=="0", "0", paste0(m1,m2) ) ,
                                dim(m1)[1], dim(m1)[2] )
    
    
    > pmat(Matr, Matr)
         [,1]   [,2]   [,3]  
    [1,] "1111" "2121" "3131"
    [2,] "1212" "2222" "3232"
    [3,] "1313" "2323" "3333"
    

    我不知道你是否准备好进行维度乘法。如果每个索引需要N个元素,那么您需要 kronecker 功能,这将需要一个稍微不同的功能:

    插入:

    也许你应该发布一个更好的测试用例?那么你本可以更明确地表达你想要什么。这说明了 克罗内克 -已应用 pmat 重新排列为数组,将得到MN[1,1]作为第一个矩阵的第一列:

     M <- matrix(c("a1","b1","c1","0"),2,2)
     N <- matrix(c("c2","d2","e2","f2"),2,2)
     MN <- array( kmat,c( 2,2,4))
     MN[ , 1,1]
    #[1] "a1c2" "a1d2"
    

    > pmat <- function(m1, m2) matrix( ifelse(m1=="0"|m2=="0", "0", paste0(m1,m2) )  )
    > kronecker(Matr, Matr, pmat)
          [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]  
     [1,] "1111" "1121" "1131" "2111" "2121" "2131" "3111" "3121" "3131"
     [2,] "1112" "1122" "1132" "2112" "2122" "2132" "3112" "3122" "3132"
     [3,] "1113" "1123" "1133" "2113" "2123" "2133" "3113" "3123" "3133"
     [4,] "1211" "1221" "1231" "2211" "2221" "2231" "3211" "3221" "3231"
     [5,] "1212" "1222" "1232" "2212" "2222" "2232" "3212" "3222" "3232"
     [6,] "1213" "1223" "1233" "2213" "2223" "2233" "3213" "3223" "3233"
     [7,] "1311" "1321" "1331" "2311" "2321" "2331" "3311" "3321" "3331"
     [8,] "1312" "1322" "1332" "2312" "2322" "2332" "3312" "3322" "3332"
     [9,] "1313" "1323" "1333" "2313" "2323" "2333" "3313" "3323" "3333"