简体   繁体   中英

Filling a matrix based on the content of another matrix in R

I want to fill one matrix based on the content of another matrix. Here are the matrices:

set.seed(135)
MAT1 <- replicate(6, sample(c("00", "01", "10", "11", "10"))); MAT1 <- t(MAT1)
rownames(MAT1) <- rep(letters[1:3], each = 2)
MAT1

  [,1] [,2] [,3] [,4] [,5]
a "00" "01" "10" "11" "10"
a "10" "00" "01" "11" "10"
b "10" "10" "00" "11" "01"
b "11" "10" "01" "00" "10"
c "10" "00" "01" "10" "11"
c "00" "10" "11" "01" "10"

LIST <- apply(X = MAT1, MARGIN = 2, FUN = unique)
MAT2 <- matrix(data = NA, nrow = 3, ncol = length(unlist(LIST)))
rownames(MAT2) <- c(letters[1:3]); colnames(MAT2) <- unlist(LIST)
MAT2 <- rbind(Hap = rep(1:length(LIST), lengths(LIST)), MAT2)
MAT2

    1  1  1  2  2  2  3  3  3  3  4  4  4  4  5  5  5
Hap 00 10 11 01 00 10 10 01 00 11 11 00 10 01 10 01 11
a   NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
b   NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
c   NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA

The first row (Hap) of MAT2 ( MAT2[1,] ) contains the modalities of each column of MAT1 but with duplicate modalities removed. In colnames(MAT2) , 1 1 1 means for the column 1 of MAT1 there are three unique modalities, 2 2 2 means for column 2 of MAT1 there are three unique modalities, etc. I want to fill MAT2 thanks to MAT1 so that for a given Hap and colnames it fills 0, 1 or 2 according to number of times that Hap appears in MAT1 . Below is the expected MAT2 :

        1  1  1  2  2  2  3  3  3  3  4  4  4  4  5  5  5
    Hap 00 10 11 01 00 10 10 01 00 11 11 00 10 01 10 01 11
    a   1  1  0  1  1  0  1  1  0  0  2  0  0  0  2  0  0
    b   0  1  1  0  0  2  0  1  1  0  1  1  0  0  1  1  0
    c   1  1  0  0  1  1  0  1  0  1  0  0  1  1  1  0  1

We split the 'MAT1' by column, loop over the list , get the table of count after stack ing into a two column dataset. Then loop over the names of the list and assign the columns in 'MAT2' that matches with the same name with the extracted list element

lst1 <- lapply(asplit(MAT1, 2), function(x) as.data.frame.matrix(table(stack(x)[2:1])))
names(lst1) <- seq_along(lst1)
for(nm in names(lst1)) {
      MAT2[-1, colnames(MAT2) == nm] <- as.matrix(lst1[[nm]])
 }

-output

MAT2
#     1    1    1    2    2    2    3    3    3    4    4    4    4    5    5    5    5   
#Hap "00" "10" "11" "10" "11" "01" "10" "00" "01" "11" "01" "10" "00" "01" "10" "11" "00"
#a   "1"  "1"  "0"  "0"  "1"  "1"  "1"  "0"  "1"  "0"  "1"  "0"  "1"  "0"  "1"  "1"  "0" 
#b   "1"  "0"  "1"  "0"  "2"  "0"  "0"  "2"  "0"  "0"  "0"  "2"  "0"  "1"  "0"  "0"  "1" 
#c   "0"  "1"  "1"  "1"  "1"  "0"  "0"  "1"  "1"  "1"  "0"  "1"  "0"  "1"  "0"  "0"  "1" 

data

MAT1 <- structure(c("00", "10", "00", "11", "10", "11", "10", "11", "10", 
"10", "10", "01", "10", "00", "01", "01", "01", "10", "11", "01", 
"10", "10", "00", "10", "01", "10", "11", "00", "11", "00"), .Dim = 6:5,
.Dimnames = list(
    c("a", "a", "b", "b", "c", "c"), NULL))

MAT2 <- structure(c("00", NA, NA, NA, "10", NA, NA, NA, "11", NA, NA, 
NA, "10", NA, NA, NA, "11", NA, NA, NA, "01", NA, NA, NA, "10", 
NA, NA, NA, "00", NA, NA, NA, "01", NA, NA, NA, "11", NA, NA, 
NA, "01", NA, NA, NA, "10", NA, NA, NA, "00", NA, NA, NA, "01", 
NA, NA, NA, "10", NA, NA, NA, "11", NA, NA, NA, "00", NA, NA, 
NA), .Dim = c(4L, 17L), .Dimnames = list(c("Hap", "a", "b", "c"
), c("1", "1", "1", "2", "2", "2", "3", "3", "3", "4", "4", "4", 
"4", "5", "5", "5", "5")))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM