Reputation: 33
I am not very experienced with R or Matlab, and I am trying to convert a Matlab code to R. The problem is, I am not exactly sure what the code does. Here is the matlab line I am having trouble with:
Wi = cell2mat(accumarray(s_group,s_u,[],@(x){repmat(sqrt(sum(x.*x)+eps),length(x),1)}));
I cannot find an R function that does the same sort of thing as the cell2mat in matlab. When I run the code with my example data, the matlab gives me an array of length 86, which is the same length as the s_group and s_u variables. However, when I use the same data with this R code:
Wi<-accumarray(s_group,s_u,sz=c(nrow(s_group),ncol(s_group)),func=function(x) matrix(sqrt(x*x),length(x),1))
it gives me the error
Error in accumarray(s_group, s_u, sz = c(length(s_group), 1), func = function(x) matrix(sqrt(x * :
Argument 'sz' does not fit with 'subs'.
I also tried it without the size specified:
Wi<-accumarray(s_group,s_u,func=function(x) matrix(sqrt(x*x),length(x),1))
and this gave me an array of length 21 with the error:
In A[i] <- func(val[subs == i]) :
number of items to replace is not a multiple of replacement length
Here is the original for-loop version from Matlab:
group_set = unique(group);
group_num = length(group_set);
Wi = zeros(n_XVar, 1);
for c = 1:group_num
idx = find(group==group_set(c));
Wc = u(idx,:);
di = sqrt(sum(sum(Wc.*Wc))+eps);
Wi(idx) = di;
end
Does anyone know what I can do to put this into R without using a for-loop? Many thanks!
Upvotes: 0
Views: 507
Reputation: 206167
It seems the cell2mat
function in Matlab turns a matrix of matrixes into a single matrix. A matrix of matrixes isn't exactly a common data type in R. But you can make one with
a<-matrix(list(), 2,2)
a[[1,1]]<-matrix(1, nrow=1)
a[[1,2]]<-matrix(2:4, nrow=1)
a[[2,1]]<-matrix(c(5,9), nrow=2)
a[[2,2]]<-matrix(c(6:8, 10:12), nrow=2, byrow=T)
(like the example on the MatLab help page for cel2mat). An R translation of that code might be
cell2mat<-function(m)
do.call(rbind, apply(m, 1, function(x) do.call(cbind,x)))
Which we can test wtih
cell2mat(a)
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 5 6 7 8
# [3,] 9 10 11 12
This is probably not the most efficient translation but it's probably the simplest.
Upvotes: 2