4 ms·
So you also think that mean(iris(iris(:,5)==2,2)) is more intuitive than mean(iris[iris$Species=="versicolor","Sepal.Width"])? Or that constructing mat
by mbq 14y ago
So you also think that
mean(iris(iris(:,5)==2,2))
is more intuitive than
mean(iris[iris$Species=="versicolor","Sepal.Width"])?
Or that constructing matrix by mapping f on 1:10 like
M=[]
for not_i=1:10
M[:,not_i]=f(not_i)
is more concise that sapply(1:10,f)?
(I know there is arrayfun, but I have never seen it used except in wow-MATLAB-is-functional blog posts)
- pseut 14y agoIronically, your "iris" object can't be a matrix the way it's written. I've had lots of students get confused about the distinction between matrices and data frames. And sapply will sometimes give (IIRC) matrices of lists with a single element if f is constructed incorrectly (requiring an explicit 'unlist' in the return statement of f). So I generally agree with you, but I think you made shared4you's point.
- mbq 14y agoNope; this entity you describe is not a matrix of lists but a single list with dimension, and sapply creates it when mapped function returns list with the same length for all iterations (which is a perfectly consistent behaviour to how sapply treats vector output). The confusion is from the fact that people think that matrices (or data frames) are R's base types -- they are not, only vectors and lists are. Matrix is just something with dim attribute, data frame is a list of equal-length elements with a proper class.
- pseut 14y agoCool, I didn't realize that lists could have dimension too. Thanks for the correction.
- psb217 14y agoOr, you could just write: M = repmat(f(1:10), n, 1); where 'n' gives the number of rows you want in 'M' and 'f' is written in proper "Matlab" style (i.e. behaves reasonably when given an array as input). Or, to be more in the spirit of linear algebra, you could write: M = ones(n,1) * f(1:10); And, if you only want one row-wise copy, you could (succinctly) write: M = f(1:10); Or, as you suggested, you could write something like: M = repmat(arrayfun(@(x)f(x), 1:10), n, 1); Or, getting more silly, and using the handy bsxfun, you could write: M = bsxfun(@times, ones(n,10), f(1:10)); If you don't feel like implementing 'f' so as to permit array inputs, you could modify this to: M = bsxfun(@times, ones(n,10), arrayfun(@(x)f(x), 1:10)); Anyhow, Matlab is very productive if you can effectively wield its powerful built-ins.
- mbq 14y agoYou didn't get my example -- it was about how to make a matrix from the results of a non-vectorised function that gets one number and returns a vector (say performs a complex simulation). The problem you've solved has an equally simple implementations in R; f(1:10) for a single copy, matrix(f(1:10),10,n) for n columns, matrix(f(1:10),n,10,byrow=T) for n rows, etc.