Reshape 3D array to match SPSS long format

Alec Jacobson

December 19, 2013

weblog/

The input format for repeated measures with two-conditions in SPSS is a little funny. In MATLAB, I would to store this data in a 3D m-by-n-by-p array where m is the number of variants across condition B, n is the number of variants across the condition in the rows, m across columns and p the number of repetitions (trials) across tubes. However, the wide format of SPSS expects repetitions to all be on the same row with flags indicating which row and column this tube corresponds to.

So if X is your m-by-n-by-p array then create a reshaped version of X and also create some index arrays:

sX = reshape(permute(X,[2 1 3]),size(X,1)*size(X,2),size(X,3));
srows = reshape(permute(rows,[2 1 3]),size(X,1)*size(X,2),1);
scols = reshape(permute(cols,[2 1 3]),size(X,1)*size(X,2),1);

Then you can combine these into one matrix:

SPSS = [srows scols sX];

So if your original data is:

>> X

X(:,:,1) =

   111   121
   211   221
   311   321


X(:,:,2) =

   112   122
   212   222
   312   322


X(:,:,3) =

   113   123
   213   223
   313   323


X(:,:,4) =

   114   124
   214   224
   314   324

Then this outputs:

>> SPSS

SPSS =

     1     1   111   112   113   114
     1     2   121   122   123   124
     2     1   211   212   213   214
     2     2   221   222   223   224
     3     1   311   312   313   314
     3     2   321   322   323   324

I guess this is a tensor equivalent of IJV format often used for sparse matrices.

Update: Here's a nasty anonymous function to convert directly:

to_spss = @(X) [reshape(permute(repmat((1:size(X,1))',[1 size(X,2)]),[2 1 3]),size(X,1)*size(X,2),1) reshape(permute(repmat((1:size(X,2)),[size(X,1) 1 1]),[2 1 3]),size(X,1)*size(X,2),1) reshape(permute(X,[2 1 3]),size(X,1)*size(X,2),size(X,3))];

Then you can just call

SPSS = to_spss(X);