Simplify loops and produce summary of list

76 views Asked by At

I have two matrices, the first (mat1) describes activities and the second (mat2) describes co-presence (alone, partner, friends).

First question : Could you help me simplify the following lines of code and get rid of the loops ! This code store in a third matrix (mat3) the activities performed in presence of each co-present (so the results of mat2). I store all the activities done alone, then with the partner, then with the friends. I store the third matrices (3 times) for each co-present in a list called MatriX.

mat1 = structure(c("1", "2", "3", "4", "5", "6", "sleep", "sleep", "sleep", 
"sleep", "sleep", "sleep", "sleep", "eat", "eat", "tv", "tv", 
"tv", "sleep", "tv", "eat", "eat", "eat", "eat"), .Dim = c(6L, 
4L), .Dimnames = list(NULL, c("id", "t1", "t2", "t3")))

mat2 = structure(c("1", "2", "3", "4", "5", "6", "partner", "partner", 
"partner", "partner", "partner", "partner", "alone", "alone", 
"alone", "partner", "partner", "partner", "alone", "friends", 
"friends", "partner", "partner", "partner"), .Dim = c(6L, 4L), .Dimnames = list(
NULL, c("id", "t1", "t2", "t3")))



MatriX = vector('list',3)

for(i in 1:3){
  MatriX[[i]] <- matrix('0', ncol = ncol(mat1), nrow = nrow(mat1))
}

  for(j in 1:ncol(mat3)){
    for(i in 1:nrow(mat3)){
      if
      (mat2[i,j] == 'alone') 
      {MatriX[[1]][i,j] <- mat1[i,j]}  
    }
  }

  for(j in 1:ncol(mat3)){
    for(i in 1:nrow(mat3)){
       if
      (mat2[i,j] == 'partner') 
      {MatriX[[2]][i,j] <- mat1[i,j]}  

    }
  }

  for(j in 1:ncol(mat3)){
    for(i in 1:nrow(mat3)){
      if
      (mat2[i,j] == 'friends') 
       {MatriX[[3]][i,j] <- mat1[i,j]}  

     }
  }

 names(MatriX) <- c('alone', 'partner', 'friends')
 MatriX

Second question : I need to get a summary of the 3 matrices stored in the list MatriX.

round(prop.table(table(MatriX$alone)), 2)
round(prop.table(table(MatriX$partner)), 2)
round(prop.table(table(MatriX$friends)), 2)

The output I would like to have could look like this one :

     Act Alone Partner Friends
1     0  0.83     0.5    0.92
2   eat  0.08    0.12    0.04
3 sleep  0.08    0.25    0.04
4    tv     0    0.12       0
1

There are 1 answers

2
akrun On BEST ANSWER

For the first part, you could remove one of the nested loop.

m1 <- matrix('0', ncol=ncol(mat1), nrow=nrow(mat1))
lst <- lapply(c('alone', 'partner', 'friends'), function(x) {
         m1[mat2==x] <- mat1[mat2==x]
         m1})
names(lst) <- c('alone', 'partner', 'friends')

The second part can be easily done by melting the 'lst' and applying table/prop.table on the long format.

library(reshape2)
round(prop.table(table(melt(lst)[3:4]), margin=2),2)
#       L1
#value   alone friends partner
#  0      0.83    0.92    0.50
#  eat    0.08    0.04    0.12
#  sleep  0.08    0.00    0.25
#  tv     0.00    0.04    0.12