Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to subtract specific elements in a list using functional programming in Mathematica?

I have a list of dates and values in the format:

{{{dateInfo1},value1},{{dateInfo2},value2},...,{{dateInfoN},valueN}}

With some actual dates and values:

{{{1971, 1, 31, 0, 0, 0.}, 1.0118}, {{1971, 2, 28, 0, 0, 0}, 1.0075},
 ..., {{2010, 5, 31, 0, 0, 0.}, 1.0403}}

For those curious, it's a list of US versus CAD $ values pulled from the FRED database.

I would like to simply subtract value1 from value 2, and then create a new list with data in the form of:

 {{{dateInfo1},0},{{dateInfo2},change1},...,{{dateInfoN},changeN-1}}

(with change1 being value2-value1)

I know there must be a relatively easy way to do this using functional programming, as opposed to Do or While with index variables and counting and all that nonsense. The method I'm trying to accomplish has to be relatively robust, because I am automatically pulling in datasets from sources that have the same formatting, but different time intervals. Replotting is then much easier if I don't have to specify the ListPlot date intervals (which would happen if I stripped the dateInfo from the list).

I am familiar with the Documentation Center and non-programming Mathematica capabilities. I have been learning programming with Mathematica, and really want to extend that ability into functional programming, but have found most of the resources on the topic a bit too difficult. I feel like I am at that hump in the learning curve where it's about to click into place, but right now I am struggling. At the very least if you have a good source on functional programming I would be more than happy to look into those! Any help is much appreciated! Sorry if it's TMI, but I'm sure many of you have felt the same way.

like image 387
Alec Avatar asked Jun 24 '10 00:06

Alec


1 Answers

You have a list of {date,value} pairs so if you Transpose that you'll have a list of two lists -- the first a list of dates and the second a list of corresponding values. You can then take the Differences of the values, Prepend 0, and then Transpose again to get back to a list of pairs.

In code,

data = {{{1971,1,31,0,0,0}, 1.0118}, 
        {{1971,2,28,0,0,0}, 1.0075}, 
        {{2010,5,31,0,0,0}, 1.0403}}
{dates, values} = Transpose[data];
diffs = Prepend[Differences[values], 0];
answer = Transpose[{dates, diffs}]

which returns:

{{{1971,1,31,0,0,0}, 0}, 
 {{1971,2,28,0,0,0}, -0.0043}, 
 {{2010,5,31,0,0,0}, 0.0328}}

To wrap that up into a single function, with thanks to Janus for the idea:

taildiffs[data_]:= 
  Transpose @ {#1, Prepend[Differences[#2], 0]}& @@ Transpose@data  

Note that the ... #1 ... #2 ... & construct is a pure function:

http://reference.wolfram.com/mathematica/ref/Function.html

The f@x syntax is simply shorthand for f[x].

Finally, f@@list is shorthand for Apply[f, list]:

http://reference.wolfram.com/mathematica/ref/Apply.html

So taildiffs as defined above is just a terse (perhaps cryptic) version of this:

Apply[Transpose[Function[{x,y}, {x, Prepend[Differences[y],0]}], Transpose[data]]
like image 63
dreeves Avatar answered Nov 12 '22 19:11

dreeves