user3791093
user3791093

Reputation: 33

R eqivalent to Matlab cell2mat function?

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

Answers (1)

MrFlick
MrFlick

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

Related Questions