Apply a function to each column of a matrix

82 views
Skip to first unread message

Fernando Saldanha

unread,
Apr 18, 2013, 4:47:16 PM4/18/13
to inca...@googlegroups.com
In R there is a function called "apply" that lets one apply a function to each column or row of a matrix or data frame.

For example,

apply(df, 2, foo)

would apply foo to each column of df.

Is there an equivalent function in Incanter? It is not hard to write but maybe there is an optimized implementation.

Thanks for your help.


Mike Anderson

unread,
Apr 18, 2013, 7:59:27 PM4/18/13
to inca...@googlegroups.com
I don't believe there is.

If it's generally useful, I'd be happy to add something like this to core.matrix. Though I think the function is more like "map" than "apply", so the naming in the Clojure ecosystem should probably reflect that. core.matrix already uses "emap" for element-wise map operations over matrices, e.g.:

(emap pow [[2 2] [2 2]] [[1 2] [3 4]])
=> [[2.0 4.0] [8.0 16.0]]
 

Fernando Saldanha

unread,
Apr 19, 2013, 12:56:58 AM4/19/13
to inca...@googlegroups.com
Thanks for your answer. 

I have been working with R for several years and I am now trying Clojure. I work mostly with time series, which makes me look at a data set as a collection of columns to which I apply operations. For example, generating an exponential moving average of each column of a matrix or data frame. This looks like an easy thing to do in a functional language. I tried writing my own functions but I don't want to reinvent the wheel.

Another question. Can one have row and column names for a matrix in Incanter?

Cheers,

F

Fernando Saldanha

unread,
Apr 19, 2013, 9:59:17 AM4/19/13
to inca...@googlegroups.com


On Thursday, April 18, 2013 5:47:16 PM UTC-3, Fernando Saldanha wrote:

Linus Ericsson

unread,
Apr 19, 2013, 11:35:06 AM4/19/13
to inca...@googlegroups.com
Incanter.zoo has some functions made for working with timeseries. Make sure to check them out!

/Linus
--
 
---
You received this message because you are subscribed to the Google Groups "Incanter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to incanter+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

un.passant

unread,
Apr 24, 2013, 11:20:36 AM4/24/13
to inca...@googlegroups.com


On Friday, April 19, 2013 1:59:27 AM UTC+2, Mike Anderson wrote:
On Friday, 19 April 2013 04:47:16 UTC+8, Fernando Saldanha wrote:
In R there is a function called "apply" that lets one apply a function to each column or row of a matrix or data frame.
Is there an equivalent function in Incanter? It is not hard to write but maybe there is an optimized implementation

I don't believe there is.

If it's generally useful, I'd be happy to add something like this to core.matrix. Though I think the function is more like "map" than "apply", so the naming in the Clojure ecosystem should probably reflect that. core.matrix already uses "emap" for element-wise map operations over matrices, e.g.:

(emap pow [[2 2] [2 2]] [[1 2] [3 4]])
=> [[2.0 4.0] [8.0 16.0]]
 

Hi,
Wouldn't it make sense to have a function giving a seq of the columns or rows of the matrix and use the regular [p]map we all love ?
Or to go the reducer way on the elts | rows | cols ?

Cheers,

B.

Mike Anderson

unread,
Apr 24, 2013, 9:09:59 PM4/24/13
to inca...@googlegroups.com
It does make sense, depending on what you want.

Indeed, in core.matrix, there is already a handy function called "slices" that takes the slices of a matrix over the first dimension (which are the rows for a 2D matrix). So you can do stuff like:

(map normalise (slices (matrix [[1 0] [0 -1] [3 4]])))
=> ([1.0 0.0] [0.0 -1.0] [0.6 0.8])

However core.matrix also has a philosophy of enabling maximum speed via protocols, so we have specialised functions for many operations. As an example: most operations with diagonal matrices are *much* faster with a specialised function rather than breaking them down into rows and recombining the processed rows into a new matrix. So we provide a protocol that enables different matrix implementations to take advantage of this.

map/pmap and reducers also have a couple of other issues from the perspective of matrix work:
- they don't work on arbitrary Java objects. So you can't use then with a Parallel Colt matrices, for example. core.matrix aims to provide a generic API that works with multiple back-end implementations, so we can't assume that everything implements sequential behaviour (sadly).
- reducers needs Clojure 1.5 minimum, an issue if you want to maintain support for 1.4 
- even reducers are quite slow compared to most aspecialised/optimised operations



Reply all
Reply to author
Forward
0 new messages