storage problem in R. alternative to nested loop for creating array of matrices and then multiple plots

前端 未结 1 712
傲寒
傲寒 2020-12-21 18:50

With the following pieces of information, I can easily create an array of matrices

b0=data.frame(b0_1=c(11.41,11.36),b0_2=c(8.767,6.950))
b1=data.frame(b1_1=         


        
相关标签:
1条回答
  • 2020-12-21 19:37

    There are a couple of other approaches you can employ.

    First, you largely have a model of b0 + b1*fu + b2*fu^2. Therefore, you could make the coefficients and apply the fu after the fact:

    ind <- expand.grid(nits = seq_len(nit), pats = seq_len(pat))
    mat_ind <- cbind(ind[, 'nits'], T.val[as.matrix(ind)])
    
    b_mat <- matrix(c(b0[mat_ind], b1[mat_ind], b2[mat_ind]), ncol = 3)
    
    b_mat
           [,1]     [,2]       [,3]
    [1,] 11.410  0.85390 -0.0130200
    [2,] 11.360  0.95650 -0.0165400
    [3,] 11.410  0.85390 -0.0130200
    [4,]  6.950  0.06752 -0.0026720
    [5,]  8.767 -0.03179 -0.0002822
    [6,] 11.360  0.95650 -0.0165400
    

    Now if we apply the model to each row, we will get all of your raw results. The only problem is that we don't match your original output - each column slice of your array is equivalent of a row slice of my matrix output.

    pt_array <- apply(b_mat, 1, function(x) x[1] + x[2] * fu.time + x[3] * fu.time^2)
    
    pt_array[1,]
    [1] 11.410 11.360 11.410  6.950  8.767 11.360
    
    pt.array1[, 1, ]
          [,1]  [,2]   [,3]
    [1,] 11.41 11.41  8.767
    [2,] 11.36  6.95 11.360
    

    That's OK because we can fix the shape of it as we get summary statistics - we just need to take the colSums and colQuantiles of each row converted to a 2 x 3 matrix:

    library(matrixStats)
    
    pt_summary = array(t(apply(pt_array,
                             1,
                             function(row) {
                               M <- matrix(row, ncol = pat)
                               c(colMeans2(M),colQuantiles(M, probs = c(0.25, 0.975))
                               )
                               }
                             )),
                       dim = c(length(fu.time), pat, 3),
                       dimnames = list(NULL, paste0('pat', seq_len(pat)), c('mean', 'LCL', 'UCL'))
    )
    
    pt_summary[1, ,] #slice at time = 1
    
            mean      LCL      UCL
    pat1 11.3850 11.37250 11.40875
    pat2  9.1800  8.06500 11.29850
    pat3 10.0635  9.41525 11.29518
    
    # rm(pt.array1)
    

    Then to do your final graphing, I simplified it - the data argument can be a subset(mydata, pt.ID == pt.no). Additionally, since the summary statistics are now in an array format, matlines allows everything to be done at once:

    par(mfrow=c(3,2))
    
    for( pt.no in 1:pat){
      plot(IPSS~pt.ID, data=subset(mydata, pt.ID == pt.no),
           xlim=c(0,57), ylim=c(0,35),
           type="l",col="black", xlab="f/u time", ylab= "",
           main = paste("patient", pt.no)
           )
    
      points(IPSS~time, data=subset(mydata, pt.ID == pt.no))
    
      matlines(y = pt_summary[,pt.no ,], x = fu.time, col=c("blue", 'green', 'green'))
    }
    

    0 讨论(0)
提交回复
热议问题