A Similar Function to R'S Rep in Matlab

A similar function to R's rep in Matlab

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.

Matlab - equivalent of R's rep() with times argument

You can use repmat or repelems, e.g.

 z = repelems(x,[1:4;rep]) 

Similar Function to Repmat in R

The equivalent of Matlab's repmat(a,2,3) in base R is kronecker(matrix(1,2,3),a).

There's also R functions repmat identical in usage to Matlab's in the R packages matlab and pracma. You can look at their source code if you like.

Element-wise array replication in Matlab

As of R2015a, there is a built-in and documented function to do this, repelem:

repelem Replicate elements of an array.

    W = repelem(V,N), with vector V and scalar N, creates a vector W where each element of V is repeated N times.

The second argument can also be a vector of the same length as V to specify the number of replications for each element. For 2D replication:

B = repelem(A,N1,N2)

No need for kron or other tricks anymore!

UPDATE: For a performance comparison with other speedy methods, please see the Q&A Repeat copies of array elements: Run-length decoding in MATLAB.

R replication in MATLAB

I'm guessing the problem that you're having is due to the ACV, in matlab you have used the code erfinv(.975) but I am guessing that you want the y and z to be close, as in the original question, if you where to change the ACV to 1.96 then you would find the same results as in the above question.

The q norm function in R:

# What is the Z-score of the 96th quantile of the normal distribution?
qnorm(.96)

credit to: http://seankross.com/notes/dpqr/

So when you change it to 1.96, the critical value from the normal, I think it should work perfectly.

A better answer would tell you how to get 1.96 rather than just putting it in (but I am not sure how to do this).

R equivalent to permuting array dimensions permute(A, dimorder) in Matlab

I believe I successfully replicated the MATLAB script in R. I don't think you actually need an equivalent for permute. In the MATLAB script, permute appears to be simply dropping excess dimensions. R does that by default unless you specify drop = FALSE when you subset an array, e.g.,

lnA[[tau, modal]] <- a[[modal]][outcomes[modal, tau],,,drop = FALSE]

If I add lnA = cell(T, NumModalities); to the MATLAB script before your final for loop and then modify the inside of the loop to be

lnA{tau, modal} = permute(a{modal}(outcomes(modal,tau),:,:,:,:,:),[2 3 4 5 6 1]);

Then I get the same array of matrices in lnA for both the MATLAB and R implementations.

In R, I use an array of lists as the equivalent of a MATLAB 2+ dimension cell array:

lnA1 = cell(T, 1); # MATLAB
lnA1 <- vector("list", Time) # R
lnA2 = cell(T, NumModalities); # MATLAB
lnA2 <- array(vector("list", Time*NumModalities), c(Time, NumModalities)) # R
lnA2 <- matrix(vector("list", Time*NumModalities), Time) # R
lnA3 = cell(T, NumModalities, 2); # MATLAB
lnA3 <- array(vector("list", Time*NumModalities*2), c(Time, NumModalities, 2)) # R

Here's the implementation:

nat_log <- function (x) { # necessary as log(0) not defined...
x <- log(x + exp(-16))
}

# Set up a list for D and A
D <- list(c(1, 0), # (left better, right better)
c(1, 0, 0, 0)) #(start, hint, choose-left, choose-right)
A <- c(rep(list(array(0, c(3, 2, 4))), 2), list(array(0, c(4, 2, 4))))

Ns <- lengths(D) # number of states in each state factor (2 and 4)
A[[1]][,,1:Ns[2]] <- matrix(c(1,1, # No Hint
0,0, # Machine-Left Hint
0,0), # Machine-Right Hint
ncol = 2, nrow = 3, byrow = TRUE)

pHA <- 1
A[[1]][,,2] <- matrix(c(0, 0, # No Hint
pHA, 1 - pHA, # Machine-Left Hint
1 - pHA, pHA), # Machine-Right Hint
nrow = 3, ncol = 2, byrow = TRUE)

A[[2]][,,1:2] <- matrix(c(1, 1, # Null
0, 0, # Loss
0, 0), # Win
ncol = 2, nrow = 3, byrow = TRUE)

pWin <- 0.8
A[[2]][,,3] <- matrix(c(0, 0, # Null
1 - pWin, pWin, # Loss
pWin, 1 - pWin), # Win
ncol = 2, nrow = 3, byrow = TRUE)

A[[2]][,,4] <- matrix(c(0, 0, # Null
pWin, 1 - pWin, # Loss
1 - pWin, pWin), # Win
ncol = 2, nrow = 3, byrow = TRUE)

for (i in 1:Ns[2]) {
A[[3]][i,,i] <- c(1,1)
}

# Set up a list of matrices:
a <- lapply(1:3, function(i) A[[i]]*200)
a[[1]][,,2] <- matrix(c(0, 0, # No Hint
0.25, 0.25, # Machine-Left Hint
0.25, 0.25), # Machine-Right Hint
nrow = 3, ncol = 2, byrow = TRUE)

outcomes <- matrix(c(1, 2, 1,
1, 1, 2,
1, 2, 4),
ncol = 3, nrow = 3, byrow = TRUE)

NumModalities <- length(a) # number of outcome factors
Time <- 3L
lnA <- array(vector("list", Time*NumModalities), c(Time, NumModalities))

for (tau in 1:Time){
for (modal in 1:NumModalities){
lnA[[tau, modal]] <- a[[modal]][outcomes[modal, tau],,]
}
}

the fastest way to replicate a vector in two direction

c and e are straightforward cases for repmat. b is different, the most common suggestion is to use kron(a', ones(2,3)) but here are some alternatives: A similar function to R's rep in Matlab

According to the many answers in that link, the fastest is possibly

reshape(repmat(a, 6, 1), 3, 6)'

MATLAB smooth function in R

One way to do this in R is use stats::convolve or use stats::filter both work just fine.

smooth <- function(y ){
h <- c(head(y, 1), mean(head(y, 3)))
t <- c(mean(tail(y, 3)), tail(y, 1))
m <- stats::convolve(y, rep(1/5, 5), type = "filter")
c(h, m, t)
}

eg:

 R> y <- c(5, 3, 7, 10, 4, 9, 12, 2, 1, 5)
R> smooth(y)
[1] 5.000000 5.000000 5.800000 6.600000 8.400000 7.400000 5.600000 5.800000
[9] 2.666667 5.000000

MATLAB:

 >> y = [5, 3, 7, 10, 4, 9, 12, 2, 1, 5]
>> smooth(y)

ans =

5.0000
5.0000
5.8000
6.6000
8.4000
7.4000
5.6000
5.8000
2.6667
5.0000

MATLAB equivalent of the R function rank()?

Yes, you can use unique():

[~, ~, rank] = unique(A); % A is the array you want to rank

Be aware that MATLAB's unique() function will settle ties differently than R's rank() function.


Alternatively, if you want to settle ties like rank(), then you can use tiedrank() instead, provided you have the Statistics Toolbox:

rank = tiedrank(A);


Related Topics



Leave a reply



Submit