0
$\begingroup$

I would like to set up a list like this data = {{Date1,y1,y2,y3,y4,y5,y6},{Date2,y1,y2,y3,y4,y5,y6},...} and then use DateListPlot to create various plots, e.g. y1 values, y2 values, and maybe also combined plots, say both y5 and y6 values for instance.

Here's the tricky bit: there are some values (let's say y3 for example) that I won't always be able to measure, which means the desired list structure from above would have to allow for "gaps" in y3, i.e. dates where I was able to measure all other y-values, but have no value for y3.

A concrete example would look something like this:

data = {{DateObject[{2022, 08, 01}, "Day", "Gregorian", -5.`], 1, 1, 1, 1, 1, 1}, {DateObject[{2022, 08, 02}, "Day", "Gregorian", -5.`], 2, 2, Missing[], 2, 2, 2}, {DateObject[{2022, 08, 04}, "Day", "Gregorian", -5.`], 4, 4, 4, 4, Missing[], 4}, {DateObject[{2022, 08, 08}, "Day", "Gregorian", -5.`], 8, 8, 8, 8, 8, Missing[]}};

Any ideas on how to achieve this and plot the outcome with DateListPlot?

Also, somewhat related: if I use the DateObject function to create the dates, e.g. DateObject[{2022, 08, 04}, "Day", "Gregorian", -5.]`, what is the significance of -5.'? This value is used in the documentation, but it's not explained what it does, and changing it to something else doesn't seem to make any difference.

(The "'" after "-5." doesn't show up in the code block since it seems that ' is used to signify code, i.e. the editor interprets ' as the end of the code block.)

$\endgroup$
4
  • 1
    $\begingroup$ Concerning your "somewhat related" question: This seems to be time zone thing. If I define d1=DateObject[{2022,08,04},"Day","Gregorian",-5] and d2=DateObject[{2022,08,04},"Day",TimeZone->-5] then they are identitcal, d1===d2, and you can also inspect them using FullForm[d1] and FullForm[d2] to see that they are identical. One can also extract the number using d1["TimeZone"]. $\endgroup$
    – user293787
    Aug 4 at 5:28
  • 1
    $\begingroup$ Try entering "Missing[]" for the missing data $\endgroup$ Aug 4 at 6:33
  • $\begingroup$ You probably meant to say that your data has the form {{Date1,y11,y12,y13,y14,y15,y16},{Date2,y21,y22,y23,y24,y25,y26},...}. I think you should provide a concrete example, including missing data, to make it easy for people here to answer your question. $\endgroup$
    – user293787
    Aug 4 at 8:13
  • $\begingroup$ Yes, you're right. Thank you both for the comments. I've edited my post above to include a concrete example. The question is how can I extract the relevant entries (for example, if I wanted to plot the yi3 values where i={1,2,3,4}) from the nested list structure? $\endgroup$ Aug 4 at 8:45

1 Answer 1

2
$\begingroup$

Given data such as

data={{DateObject[{2022,08,01},"Day","Gregorian",-5.`],3.,2.2,2.4,2.5,7.6,5.9},
      {DateObject[{2022,08,02},"Day","Gregorian",-5.`],2.9,3.9,Missing[],2.4,1.4,2.2},
      {DateObject[{2022,08,04},"Day","Gregorian",-5.`],7.5,Missing[],5.,2.2,5.4,4.9},
      {DateObject[{2022,08,08},"Day","Gregorian",-5.`],4.1,2.1,7.9,7.7,5.1,Missing[]}};

We can extract data using:

extractData[x_Integer]:=data[[;;,{1,x+1}]];
extractData[x_List]:=Map[extractData,x];

Try extractData[1] or extractData[{1,3}] to see what this does. We can then plot using

plot[x_,drop_]:=DateListPlot[extractData[x]/.If[drop,{_,Missing[]}->Nothing,{}],
                             PlotMarkers->Automatic,PlotLegends->x];

The drop determines how we deal with the missing data. For example

plot[{1,3,5},False]

gives

enter image description here

whereas

plot[{1,3,5},True]

gives

enter image description here

$\endgroup$
6
  • $\begingroup$ This is brilliant. Thank you so much! How would I plot something like fractions yi3/yi4 for all i where there is no missing data or differences like yi1-yj1 where i = j+1 (i.e. differences between two consecutive days where this data is available)? I've already accepted your answer since it covers everything I initially asked for. I'm just trying to better understand the functionality of the extract data functions you've coded and how their use cases could be extended to the divisions and subtractions I've mentioned above. $\endgroup$ Aug 4 at 12:39
  • $\begingroup$ I guess the latter (differences of the same y-value between consecutive days) is a bit trickier because even if there is no missing data there may be gaps in the dates (i.e. no measurements on certain days) that prevent extracting the sought after difference. $\endgroup$ Aug 4 at 12:47
  • $\begingroup$ OK so I figured out that I can use extractData[3][[;; , 2]]/extractData[4][[;; , 2]] to get a list of all fractions yi3/yi4. Now I'm looking for a way to automatically discard those elements in the list that involve missing data. I'm guessing something like Select[] that selects all elements that do not contain the string "Missing"? $\endgroup$ Aug 4 at 13:18
  • $\begingroup$ Success! I've come up with Select[Transpose[{extractData[1][[;; , 1]], extractData[3][[;; , 2]]/extractData[4][[;; , 2]]}], #[[2]] < 1 &] which discards the elements containing missing data. It's a bit of a cheat because I know that in this particular case the fractions yi3/yi4 cannot be ≥ 1, but it gets the job done for now. If you know how to deal with the more complicated differences for consecutive days please let me know. $\endgroup$ Aug 4 at 13:40
  • $\begingroup$ Sorry, I was offline for a while, but seems you figured most things out yourself ;-) You could use Select[...,FreeQ[#,Missing[]]&] to remove things that contain Missing[]. Btw, in general it is useful to think carefully about how data is organized. Here a good alternative might be an Association as in data2 = <|Date1->{y11,y12,y13,y14,y15,y16},Date2->{y21,y22,y23,y24,y25,y26}|>. This better reflects the fact that the date and the values play different roles. One can extract data using something like Map[#[[2]]&,data2]. Good luck! $\endgroup$
    – user293787
    Aug 4 at 18:47

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.