How to subtract certain 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 meanings:

 {{{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 the curious, this is a list of US vs. CAD $ values ​​torn from the FRED database .

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

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

(with change1 is value2-value1)

I know that there should be a relatively simple way to do this using functional programming, unlike Do or While with index variables and counts and all this bullshit. The method I'm trying to execute should be relatively reliable because I automatically extract data from sources that have the same formatting but different time intervals. Then Replotting is much simpler if I don't need to specify ListPlot date intervals (what happens if I remove DateInfo from the list).

I am familiar with the Documentation Center and not the Mathematica Feature Programming. I study programming with Mathematica and really want to extend this functionality in functional programming, but I found most of the resources in this topic are too complicated. I feel like I'm on this hump on a learning curve where he is about to click in place, but now I'm afraid. At least if you have a good source of functional programming, I would be more than happy to look into them! Any help is much appreciated! Sorry if this is TMI, but I'm sure many of you have felt the same way.

+6
date list wolfram-mathematica functional-programming
source share
5 answers

You have a list of pairs {date, value}, so if you are Transpose , you will have a list of two lists - the first list of dates, and the second - a list of corresponding values. You can then take the Differences values, Prepend 0, and then transpose again to return to the 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 this in one function, thanks Janus for the idea:

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

Please note that the construction ... #1 ... #2 ... & is a pure function:

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

The syntax of f@x simply abbreviated for f[x] .

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

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

So taildiffs, as defined above, is just a brief (possibly cryptic) version of this:

 Apply[Transpose[Function[{x,y}, {x, Prepend[Differences[y],0]}], Transpose[data]] 
+7
source share

Except that you want to use a starting 0 , you are looking for Differences . To leave only the dates, transfer and apply to the second part, for example:

 TailDifferences[data_]:= Transpose@Apply [{#1,{0}~Join~Differences[#2]}&,Transpose[data]] 

Applying this to your data will give you something like this:

 data={{{dateInfo1},value1},{{dateInfo2},value2},{{dateInfo3},value3}}; TailDifferences[data] {{{dateInfo1},0},{{dateInfo2},-value1+value2},{{dateInfo3},-value2+value3}} 
+3
source share
 data = {{{dateInfo1}, value1}, {{dateInfo2}, value2}, {{dateInfo3}, value3}} Map[{#[[2,1]], #[[2,2]] - #[[1,2]]}&, {Take[data, Length[data] - 1], Rest[data]}] 

gives

 {{{dateInfo2}, -value1 + value2}, {{dateInfo3}, -value2 + value3}} 

This is the first item in the result list.

 {{dateInfo1},0} 

doesn't fit in the sequence, so you can manually add it to the list

+2
source share

I recommend using Reap and Sow for this:

 In[13]:= lis= {{{1971,1,31,0,0,0.},1.0118},{{1971,2,28,0,0,0},1.0075},{{2010,5,31,0,0,0.},1.0403}}; In[14]:= First@Last @Reap[ (* set first previous to first value to get 0 *) Module[{prev = lis[[1, 2]]}, Scan[ ( (* First[#] = date, Last[#] = value *) Sow[{First[#], Last[#] - prev}]; (* set new previous to this value *) prev = Last[#] ) &, lis]] ] Out[14]= {{{1971, 1, 31, 0, 0, 0.}, 0.}, {{1971, 2, 28, 0, 0, 0}, -0.0043}, {{2010, 5, 31, 0, 0, 0.}, 0.0328}} 

Reap conclusion is a little more complicated if you are not familiar with it, but Reap and Sow basically give you a way to β€œsow” things into lists and then β€œreap” them after evaluating. Reap and Sow much more efficient than using AppendTo with a list, for example.

NTN!

+2
source share

This operation can also be performed using Part and Set :

 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}}; Module[{a = data}, a[[2 ;;, 2]] = Differences[a[[All, 2]]]; a[[1, 2]] = 0; a ] 
  {{{1971, 1, 31, 0, 0, 0}, 0},
  {{1971, 2, 28, 0, 0, 0}, -0.0043},
  {{2010, 5, 31, 0, 0, 0}, 0.0328}} 
+1
source share

All Articles