I'm looking to do the following: 1° Use a loop in R to create matrices 2° Once these matrices are created I want to stack them
For example I have tried : (please see inside the code what I try to do)
S = 5
n = 100
B = 2
alpha=0.3
beta=1.2
sim_original_samples <- matrix(0, S , n)
sim_original_samples_X_bar <- matrix(0, S, 1)
for (i in 1:S) {
sim_original_samples[i,] <- rgamma(n, alpha, beta)
# here I simulate 5 samples from a gamma distribution
sim_original_samples_X_bar[i] <- mean(sim_original_samples[i])
# here I compute the sample average for each one
##
for (j in 1:B) {
matrix_j <- sample(sim_original_samples[i],n,replace=TRUE)
# for each sample i, I want to draw a new sample
# I want to repeat this B times
# thus matrix_j is a (1*n) matrix of the observations
# instead of writing matrix_1 = ... , matrix_B = ... I want to loop this
# however, this command doesn't work
#
# next once I have created this B matrices per sample i I want to compute the sample average
matrix_j_av <- mean(matrix_j)
# again, I want to do this for every matrices from 1 to B
#
# next, I want to stack these matrices
# first the matrix of all samples
matrix_big <- list(matrix_j)
# that is, its first element is for the original sample n°1, the first resampling
# its second element is, for the original sample n°2, the second resampling
# and so on, last element, for sample n°S, resampling n°B
# I guess this matrix is of dimension S*B * n
#
# I want to do exactly the same for the matrix of sample means
matrix_big_sample <- list(mean_matrix_j)
# which I guess is of dimension S*B * 1
How do I do all of this ? PS : for those of you who had a doubt, yes it is Bootstrap method ;)
CodePudding user response:
The Question
Let's divide your question into a two parts:
- How to create the data: samples, re-samples, means, etc.
- How to create a multi-dimensional object
1. Creating the data
Configuration from your question
S <- 5
n <- 100
B <- 2
alpha <- 0.3
beta <- 1.2
Sample and re-sample
require( tidyverse )
U <- map_dfc( 1:S, ~rgamma( n, alpha, beta ))
Ubar <- map_dfc( 1:S, mean )
V <- map_dfc( 1:S, ~sample( U[[ . ]], n, replace = TRUE ))
Vbar <- map_dfc( 1:S, mean )
What shape are these?
dim( U )
# 100 5
dim( V )
# 100 5
dim( Ubar )
# 1 5
dim( Vbar )
# 1 5
Now, what did you want to stack? (and why?)
2. How to create a multi-dimensional object
Sometimes it can be helpful to pack data into a multi-dimensional object, in order to facilitate slicing along axes, or to select specific elements.
Define the object
multi_dimensional <- array(
data = 0:( S * B * n )
, dim = c( S, B, n )
, dimnames = list( # <---- names are optional
paste0( 'X', 1:S )
, paste0( 'Y', 1:B )
, paste0( 'Z', 1:n )
)
)
dim( multi_dimensional )
# [1] 5 2 100
Slice, dice, and chop
multi_dimensional[ 1, 1, 1 ]
# [1] 0
multi_dimensional[ S, B, n ]
# [1] 999
multi_dimensional[ 1, 2, 1:10]
# Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 Z10
# 5 15 25 35 45 55 65 75 85 95
multi_dimensional[ , , 1:2 ]
# , , Z1
#
# Y1 Y2
# X1 0 5
# X2 1 6
# X3 2 7
# X4 3 8
# X5 4 9
#
# , , Z2
#
# Y1 Y2
# X1 10 15
# X2 11 16
# X3 12 17
# X4 13 18
# X5 14 19
multi_dimensional[ S, B, 99:100 ]
# Z99 Z100
# 989 999
Use the named dimensions, if you wish
multi_dimensional[ , , c( 'Z1', 'Z2' ) ]
# , , Z1
#
# Y1 Y2
# X1 0 5
# X2 1 6
# X3 2 7
# X4 3 8
# X5 4 9
#
# , , Z2
#
# Y1 Y2
# X1 10 15
# X2 11 16
# X3 12 17
# X4 13 18
# X5 14 19
multi_dimensional[ c( 'X1', 'X3', 'X5' ), 'Y2' , c( 'Z1', 'Z2' ) ]
# Z1 Z2
# X1 5 15
# X3 7 17
# X5 9 19
Assign new values to specific elements
multi_dimensional[ 5, 1, 29:30 ] <- c( 124.76, -5.0002 )
Now show the new values
multi_dimensional[ 5, 1, 29:30 ]
# Z29 Z30
# 124.8 -5.0
multi_dimensional[ 1:3, , 91:100 ] # slice off a particular 3 x 10 block
# (not shown, due to size)
CodePudding user response:
I think you misunderstoond the purpose of matrix datatype as in R matrices can't store complex objects such as other matrices, they are limited to: double/numeric, integer, logical, character, complex and raw.
What you seem to want is to be able to store a list of B matrices of arbitrary size (1 by n) that are generated on the second loop. You can declare an empty list and start adding the matrices in the second loop to it with something like this:
#You can declare this outside the loops.
matrix_j <- vector(mode='list', length=B)
#Then on the inner loop you can use [[]] to add elements to a list
for (j in 1:B) {
matrix_j[[j]] <- sample(sim_original_samples[i],n,replace=TRUE)
or if you want an empty list of size 0, you can do matrix_j <- list()
instead.
Next i didn't get if you want to compute the mean of each sample inside the list or if you want to compute the mean of the whole set of numbers, so:
- First one would require you to you use the list apply function
lapply
,like this:lapply(matrix_j,mean)
, which would return a list in which each element is the mean of the the element in the same position ofmatrix_j
. - For the second possibility, i think it would be more appropriate to combine the list elements into one simpler data structure and then compute the mean.
For your last problem, it seems to me that using lists
(lists of lists) would solve your issue.
I'd create a big empty list and then add other lists as elements, as lists are allowed to contain other lists.