Search code examples
rmatrixreplaceassignsubmatrix

Assigning values from submatrices to larger matrix


I have a bunch of small matrices, which are basically subsets of a larger matrix, but have different values. I want to take the values from these submatrices and overwrite the corresponding values in the larger matrix. For instance, say this is my larger matrix:

        AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000   6.5      NA    -1.8    3.65    -17.96  -26.5
AB-2600    NA     7.18    NA      NA       NA      NA
AB-3500  -1.79     NA     5.4     NA     -4.63     NA
AC-0100   3.65     NA     NA     4.22     9.8      NA
AD-0100 -17.96     NA    -4.63    9.8     5.9      NA
AF-0200 -26.5      NA     NA      NA       NA     4.28

A smaller matrix might just be:

        AB-2000 AB-3500
AB-2000    5.5    2.5
AB-3500    2.5    6.5

So, for instance, I want to take the value from the intersection of the AB-2000 row and AB-3500 column in the smaller matrix (2.5) and set it as the new value in the larger matrix, and do the same thing for the other values in the submatrix so we get a new larger matrix that looks like:

         AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000    5.5      NA     2.5    3.65   -17.96   -26.5
AB-2600     NA     7.18    NA      NA      NA      NA
AB-3500    2.5      NA     6.5     NA     -4.63    NA
AC-0100    3.65     NA     NA     4.22     9.8     NA
AD-0100  -17.96     NA    -4.63   9.8      5.9     NA
AF-0200  -26.5      NA     NA      NA      NA     4.28

I have a lot of submatrices whose values I am using to override the values in the larger matrix so want a way to do this efficiently. Any thoughts?


Solution

  • You can take advantage of having equal rownames and colnames in all matrices and just subset the big matrix according to the submatrix, and then replace the values:

    X <- read.table(text="        AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
    AB-2000   6.5      NA    -1.8    3.65    -17.96  -26.5
    AB-2600    NA     7.18    NA      NA       NA      NA
    AB-3500  -1.79     NA     5.4     NA     -4.63     NA
    AC-0100   3.65     NA     NA     4.22     9.8      NA
    AD-0100 -17.96     NA    -4.63    9.8     5.9      NA
    AF-0200 -26.5      NA     NA      NA       NA     4.28")
    X
    
    x1 <- read.table(text="        AB-2000 AB-3500
    AB-2000    5.5    2.5
    AB-3500    2.5    6.5")
    
    X[rownames(x1),colnames(x1)] <- x1
    

    Result:

    > X
            AB.2000 AB.2600 AB.3500 AC.0100 AD.0100 AF.0200
    AB-2000    5.50      NA    2.50    3.65  -17.96  -26.50
    AB-2600      NA    7.18      NA      NA      NA      NA
    AB-3500    2.50      NA    6.50      NA   -4.63      NA
    AC-0100    3.65      NA      NA    4.22    9.80      NA
    AD-0100  -17.96      NA   -4.63    9.80    5.90      NA
    AF-0200  -26.50      NA      NA      NA      NA    4.28
    

    For more than one submatrix, you can do something like this:

    x2 <- read.table(text="        AB-2600 AC-0100
    AB-2600    42    42
    AC-0100    42    42") #Fake data
    
    all.sub <- list(x1, x2)
    
    for(x in all.sub) X[rownames(x),colnames(x)] <- x
    
    > X
            AB.2000 AB.2600 AB.3500 AC.0100 AD.0100 AF.0200
    AB-2000    5.50      NA    2.50    3.65  -17.96  -26.50
    AB-2600      NA    42.1      NA   42.20      NA      NA
    AB-3500    2.50      NA    6.50      NA   -4.63      NA
    AC-0100    3.65    42.3      NA   42.40    9.80      NA
    AD-0100  -17.96      NA   -4.63    9.80    5.90      NA
    AF-0200  -26.50      NA      NA      NA      NA    4.28
    

    Just keep in mind that if you have repeated occurrences of [row,col] the last submatrix in all.sub will be the final value in X.