A similar function to R's rep in Matlab

<>

This question already has an answer here:

Answers


You can reproduce the syntax of the rep function in R fairly closely by first defining a function as follows:

function [result]=rep(array, count)
matrix = repmat(array, count,1);
result = matrix(:);

Then you can reproduce the desired behavior by calling with either a row or column vector:

>> rep([1 2 3],3)
ans =
 1     1     1     2     2     2     3     3     3

>> rep([1 2 3]',3)
ans =
 1     2     3     1     2     3     1     2     3

Note I have used the transpose (') operator in the second call to pass the input array as a column vector (a 3x1 matrix).

I benchmarked this on my laptop, and for a base array with 100,000 elements repeated 100 times, it was between 2 to 8 times faster than using the ceil option above, depending on whether you want the first or the second arrangement.


Good question +1. A neat one-liner method to accomplish this is via the Kronecker tensor product, eg:

A = [1 2 3];
N = 3;
B = kron(A, ones(1, N));

Then:

B =

     1     1     1     2     2     2     3     3     3

UPDATE: @Dan has provided a very neat solution that looks to be more efficient than my kron method, so check that answer out before leaving the page :-)

UPDATE: @bcumming has also provided a nice solution that should scale very nicely when the input vector is large.


If like me you have no idea what a Kronecker tensor product is you might be interested in this more intuitive (and actually I think faster) solution:

c(ceil((1:length(c)*n)/n));

so here I used vector indexing to replicate the matrix. For example using the two case you have above we could do:

c = 1:3;
c([1 1 1 2 2 2 3 3 3]) %for each
c([1 2 3 1 2 3 1 2 3]) %for times

so the questions is how do we make a vector [1 2 3 1 2 3 1 2 3] without the very functionality you are requesting. So I made a vector with the number of elements we need i.e. 1:9 and then divide by three and round up (i.e. try ceil((1:9)/3) in the command line.

A bit of benchmarking (I know this stuff should be in loops so maybe this isn't so accurate):

c = 1:3; n = 3;
tic; k = kron(c, ones(1, n)); toc; % 0.000208 seconds.
tic; a = c(ceil((1:length(c)*n)/n)); toc;  % 0.000025 seconds.
clear;
c = 1:1000000; n = 3;
tic; k = kron(c, ones(1, n)); toc; % 0.143747 seconds.
tic; a = c(ceil((1:length(c)*n)/n)); toc;  % 0.090956 seconds.
clear;
c = 1:10000; n = 1000;
tic; k = kron(c, ones(1, n)); toc; % 0.583336 seconds.
tic; a = c(ceil((1:length(c)*n)/n)); toc;  % 0.237878 seconds.

Here's one idea:

a=[1,2,3];
reshape(repmat(a,1,length(a)),1,length(a)^2)

ans =

 1     2     3     1     2     3     1     2     3

reshape(repmat(a,length(a),1),1,length(a)^2)

ans =

 1     1     1     2     2     2     3     3     3

I can't yet find a simpler function that does this in one step, interested if there is one though.


Need Your Help

Java copy section of array

java arrays copy java1.4

Is there a method that will copy a section of an array(not arraylist) and make a new array from it?

jupyter notebook running kernel in different env

python packages jupyter conda virtual-environment

I've gotten myself into some kind of horrible virtualenv mess. Help?!