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 vectorV
and scalarN
, creates a vectorW
where each element ofV
is repeatedN
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
Replace All Particular Values in a Data Frame
How to Add Code Folding to Output Chunks in Rmarkdown HTML Documents
Ggplot Combining Two Plots from Different Data.Frames
Forcing Garbage Collection to Run in R With the Gc() Command
Locate the ".Rprofile" File Generating Default Options
Using Regex in R to Find Strings as Whole Words (But Not Strings as Part of Words)
Calculating Cumulative Sum For Each Row
Clang-7: Error: Linker Command Failed With Exit Code 1 For Macos Big Sur
Extracting the Last N Characters from a String in R
Plot With Conditional Colors Based on Values in R
Pass a Vector of Variables into Lm() Formula
Dplyr Filter: Get Rows With Minimum of Variable, But Only the First If Multiple Minima
What Are Replacement Functions in R