R: convert JAGS output matrix to array based on column names - arrays

In R, I have a JAGS model output (made in parallel with jags.parfit from the dclone package) that is a list of six 2-dimensional matrices (corresponding to six chains each with 3000 reps) with column names equivalent to the indices of an array. The first digit has 3 unique values, the second 2000, the third 4, and the fourth 6.
head(colnames(m1[[1]]))
[1] "y.pred[1,1,1,1]" "y.pred[2,1,1,1]" "y.pred[3,1,1,1]" "y.pred[1,2,1,1]" "y.pred[2,2,1,1]" "y.pred[3,2,1,1]"
I want to convert this long-form matrix into an array with 5 dimensions which correspond to the 3000 reps as row and the 4 indices from the column names as new columns. This array will have the following dimensions:
dim(m1.array)
[1] 3000 3 2000 4 6
Is there a relatively straightforward way to do this?
UPDATE
Based on the below suggestion, I was able to convert each matrix to the expected array with the following code:
m1.arrayList <- lapply(m1, function(x) array(x, dim = c(3000, 3, 2000, 4, 6)))
I was then able to convert the list of 5-dim arrays into a 6-dim array with:
m1.array <- simplify2array(m1.arrayList)

Related

How to exact numbers from an array in a cell

In one of the columns of my df, the values in the cell are reported as an array (e.g. [1,2,3,4,8]) as opposed to being just single numbers. This is because the question was a "select all that apply" question.
However, when I try to count how many of each number occurs, I am not able to do so because these numbers are nested within a list. How can I extract the numbers so that I am able to count them?
For example:
row 1: [1,2,3,4,8]
row 2: [3]
row 3: [1,2,3,4]
I want to be able to run a statement such as: nrow(df[df$column == 1,]) that will count all of the occurrences of the number 1. So, in this case, the output would be 2, but right now it says 0.
Here is a method using base R:
# set up data
df <- as.data.frame(c('[1,2,3,4,8]', '[3]', '[1,2,3,4]'))
colnames(df) <- c('data')
# strip off starting and ending brackets
stripped <- substr(df$data, 2, nchar(df$data)-1)
# split each row by comma
split <- strsplit(stripped, ',')
# flatten the list of numbers to a vector
numbers <- unlist(split)
# view table of frequency of each number
table(numbers)
output:
numbers
1 2 3 4 8
2 2 3 2 1
getting count of a single number
# view count of a single number
length(which(numbers == '8'))
output:
[1] 1

Fill an array by specific columns in R

This might be a simple question, but I'm new to R and having trouble figuring it out. I've tried searching extensively for the answer and I cannot come up with it.
I have a dataframe that is 92:24. I would like to create an array that is (92, 2, 12) which is populated from the columns in the dataframe. I would like column 1 and 2 to be "stacked", columns 3 and 4, columns 5 and 6, and so on. The first dimension of the array should correspond to all the odd columns and the second dimension should correspond to all the even columns, with 92 rows and 12 columns in each of the 2 dimensions.
Any help would be greatly appreciated.
Thank you!
Maybe this does what you want.
First, create a data.frame with the appropriate dimensions.
dat <- as.data.frame(matrix(1:2208, ncol = 24))
Then, it's just a columns' shuffle and dim trick.
mat <- as.matrix(dat)
mat <- mat[, c((1:12)*2 - 1, (1:12)*2)]
dim(mat) <- c(92, 12, 2)
# See the first 5 rows
mat[1:5, , ]

Structure array assigning

I have a 1x5 structure array called Game with two fields i.e.
Game(5) = struct(Points, Scorers);
Now, I also have a cell-array (5x2 cell array) (imported from xlsread - so its all in cell-array form).
pts = [1 2;3 4;5 6;7 8;9 10];
How should I go about assigning each row of pts, to each of the 5 structures in Game, respectively?
For example: Game(3).Points should be row 3 of pts (which is [5 6]).
Game(2).Points should be [3 4]. Game(1).Points will be [1 2].
If your worksheet is organized such that rows correspond to observations and columns correspond to variables - e.g. points (numeric) and scorers (string) - you can import the data into Matlab using:
[pts, scr] = xlsread(file);
Then you can simply read the matrix pts and cell array scr into each field of a structure array as:
Game = struct('Points', num2cell(pts,2), 'Scorers', scr);
This takes advantage of struct()'s built-in ability to match output dimensions to its inputs, avoiding the use of a for loop to iteratively assign imported values to the fields.

How to convert a cell array of 2D matrices into a multidimensional array in MATLAB

In MATLAB, I have a defined cell array C of
size(C) = 1 by 150
Each matrix T of this cell C is of size
size(C{i}) = 8 by 16
I am wondering if there is a way to define a new multidimension (3D) matrix M that is of size 8 by 16 by 150
That is when I write the command size(M) I get 8 by 16 by 150
Thank you! Looking forward for your answers
If I'm understanding your problem correctly, you have a cell array of 150 cells, and each cell element is 8 x 16, and you wish to stack all of these matrices together in the third dimension so you have a 3D matrix of size 8 x 16 x 150.
It's a simple as:
M = cat(3, C{:});
This syntax may look strange, but it's very valid. The command cat performs concatenation of matrices where the first parameter is the dimension you want to concatenate to... so in your case, that's the third dimension, and the parameters after are the matrices you want to concatenate to make the final matrix.
Doing C{:} creates what is known as a comma-separated list. This is equivalent to typing out the following syntax in MATLAB:
C{1}, C{2}, C{3}, ..., C{150}
Therefore, by doing cat(3, C{:});, what you're really doing is:
cat(3, C{1}, C{2}, C{3}, ..., C{150});
As such, you're taking all of the 150 cells and concatenating them all together in the third dimension. However, instead of having to type out 150 individual cell entries, that is encapsulated by creating a comma-separated list via C{:}.

Create a matrix from three column vectors

I have three column vectors, then I want to creat matrix from this column victors
A1(:);
A2(:);
A3(:)
each column vectors has 25 element then the new matrix C will be a matrix with 3x25
I want to make A1(:) the first column of matrix c
A2(:) second column
A3(:) third column
Use cat to concatenate along dimension 1 or 2 depending on how you input those three vectors.
Thus, you can use -
C = cat(2,A1(:),A2(:),A3(:)).'
Or
C = cat(1,A1(:).',A2(:).',A3(:).')
Of course, you can skip (:)'s, if you know that all those are column vectors.
The above two approaches assumes that you intend to get an output of size 3 x N, where is N is the number of elements in the column vectors. If you were looking to get an output of size N x 3 , i.e. where each column is formed from the elements of column vectors A1, A2 and so on, just drop the transpose from the first of the two approaches mentioned above. Thus, use this -
C = cat(2,A1(:),A2(:),A3(:))

Resources