3
$\begingroup$

I often have data in the form of

YEAR    JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
1950    -1.022  -1.146  -1.289  -1.058  -1.419  -1.36   -1.334  -1.05   -0.578  -0.395  -1.151  -1.248
1951    -1.068  -1.196  -1.208  -0.437  -0.273  0.48    0.747   0.858   0.776   0.75    0.729   0.466
1952    0.406   0.131   0.086   0.262   -0.267  -0.634  -0.231  -0.156  0.362   0.309   -0.34   -0.124
1953    0.024   0.379   0.263   0.712   0.84    0.241   0.416   0.253   0.524   0.092   0.049   0.314
-0.093  -0.312
and so on ...

I want to convert this into time/value tuples of the type that can be easily plotted using DateListPlot. I have written some very hackish code that does the job, but it feels messy and unsatisfactory. Does anyone know of an elegant 'Mathematica' way to do this?

$\endgroup$
2
  • 2
    $\begingroup$ Where do you have that data? In a text file? $\endgroup$ Jan 30 '14 at 1:26
  • $\begingroup$ Yes. The original data is here - esrl.noaa.gov/psd/enso/mei/table.html I copy/paste it and get rid or the garbage at top. Make CSV in Excel and load into Mathematica. But it's just an example. I have many others, usually financial data. $\endgroup$
    – user9444
    Jan 30 '14 at 1:36
6
$\begingroup$

Here's what I came up with...

data = {{"YEAR" , "JAN", "FEB", "MAR", "APR", "MAY" , "JUN" , "JUL", 
  "AUG", "SEP" , "OCT", "NOV" , "DEC"},
{1950, -1.022, -1.146, -1.289, -1.058, -1.419, -1.36, -1.334, -1.05, 
-0.578, -0.395, -1.151, -1.248},
{1951, -1.068, -1.196, -1.208, -0.437, -0.273, 0.48, 0.747, 0.858, 
0.776, 0.75, 0.729, 0.466},
{1952, 0.406, 0.131, 0.086, 0.262, -0.267, -0.634, -0.231, -0.156, 
0.362, 0.309, -0.34, -0.124},
{1953, 0.024 , 0.379, 0.263, 0.712, 0.84, 0.241, 0.416, 0.253, 
0.524, 0.092, 0.049, 0.314}};

Since the data is arranged per month, we can build the dates as such...

Thread[{#[[1]], Range[12]}] & /@ Rest@data

Now, we can Transpose in the data and plot away...

Transpose[{Thread[{#[[1]], Range[12]}], Rest@#}] & /@ Rest@data

DateListPlot[%, Joined->True]

enter image description here

You can also plot as one series by using Flatten at level 1.

DateListPlot[
 Flatten[Transpose[{Thread[{#[[1]], Range[12]}], Rest@#}] & /@ 
 Rest@data, 1], Joined -> True]

enter image description here

UPDATE

Just saw where the actual data is located which can be imported:

data = Cases[
  Import["http://www.esrl.noaa.gov/psd/enso/mei/table.html", 
  "Table"], {_?NumberQ, __}];

enter image description here

$\endgroup$
2
  • $\begingroup$ That looks pretty good. I was thinking about 'Thread', but I'm not experienced with it and my first attempts didn't work. $\endgroup$
    – user9444
    Jan 30 '14 at 1:40
  • $\begingroup$ Great! Love the addition of the import from scratch. Thanks. $\endgroup$
    – user9444
    Jan 30 '14 at 1:45
3
$\begingroup$

I'll assume your data is on file (named datas.txt) as you suggested in your comment. Then:

data = ReadList["datas.txt", Word, RecordLists -> True]

Gives

{{"YEAR", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", 
  "SEP", "OCT", "NOV", "DEC"}, {"1950", "-1.022", "-1.146", "-1.289", 
  "-1.058", "-1.419", "-1.36", "-1.334", "-1.05", "-0.578", "-0.395", 
  "-1.151", "-1.248"}, {"1951", "-1.068", "-1.196", "-1.208", 
  "-0.437", "-0.273", "0.48", "0.747", "0.858", "0.776", "0.75", 
  "0.729", "0.466"}, {"1952", "0.406", "0.131", "0.086", "0.262", 
  "-0.267", "-0.634", "-0.231", "-0.156", "0.362", "0.309", "-0.34", 
  "-0.124"}, {"1953", "0.024", "0.379", "0.263", "0.712", "0.84", 
  "0.241", "0.416", "0.253", "0.524", "0.092", "0.049", "0.314"}}

Now, very crude, but I had to approach this differently from kale's elegant method:

   pl = Table[{StringJoin[data[[1, #]], " ", data[[k, 1]]], 
        ToExpression[data[[k, #]]]} & /@ Range[2, 13], {k, 2, Length@data}]

Finally,

DateListPlot[pl, Joined -> True, PlotStyle -> Thick]

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ +1 for the ReadList function, which I wasn't aware of. $\endgroup$
    – user9444
    Jan 30 '14 at 18:07
  • $\begingroup$ @IanSchumacher. Thanks. Also, note that for very large data, ReadList is much faster than Import $\endgroup$
    – RunnyKine
    Jan 30 '14 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy