Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to calculate date_month variable from Date (dmy) and day of year (doy)

    Hi,

    I have been wondering if there is a way to present average annual statistics from time-series data on a graph with only Date and Month, instead of day of year (doy)?
    I have to do a lot of graphs of that kind

    thanks in advance

  • #2
    Code:
    webuse sp500
    line open date, xlab(,format(%tdm-Y)) scheme(s1color)
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	88.2 KB
ID:	1635399

    Comment


    • #3
      Thanks it is helpful for the averages. Unfortunately I also need to plot each year (10 years) time-series (10 lines ) on the same graph, I used to use doy for that, but it is not an option now .

      Comment


      • #4
        If years each cover about 1/10 of the axis, they can't be considered points any more. Here is an approach based on

        1. Ticks every 1 January.

        2. Year labels every 1 July.

        Note that this is just recycling advice already long published as at https://www.stata-journal.com/articl...article=gr0030


        Code:
        clear 
        local max = mdy(12, 31, 2020)
        local min = mdy(1, 1, 2011)
        set seed 2803 
        set obs `=`max' - `min' + 1'
        gen t = mdy(12, 31, 2010) + _n 
        format t %td 
        gen y = rnormal()
        line y t 
        
        forval y = 2011/2021 {
            local tick =  mdy(1,1,`y')
            if `y' < 2021 { 
                local label = mdy(7, 1, `y')
                local call `call' `label' "`y'"
            } 
            local ticks `ticks' `tick'
        }
        
        line y t, xticks(`ticks', tlength(*3)) xla(`call', tlc(none) tlength(*0.2)) scheme(s1color)
        Click image for larger version

Name:	interval.png
Views:	1
Size:	112.8 KB
ID:	1635455

        Comment


        • #5
          Thank you a lot, Nick. However, the graph you published is not the one I need to obtain. I need a graph, that visually presents how the concentrations are changing within 365 days ( actually I have biological measurements and they are not present all the year, but some months) for different years. So on x-axis I need to have 1 Jan, 2 Jan, 3 Jan.... 31 Dec (that is why I used to use day of year previously (doy), but this type of graph is hard to read) and I would plot different two-way lines, each presenting the concentrations measured in one of the years. what I need is just similar to day of year on x-axis, but presented as days of months. so that it would be visible straight away how the concentrations were different within June for example in different years.
          Last edited by Julia Ol; 09 Nov 2021, 02:00.

          Comment


          • #6
            You did say that -- reading backwards.


            It's the same technique really. Your day of the year is slightly different for leap years, but we can fuzz over that.

            Code:
            clear 
            local max = mdy(12, 31, 2020)
            local min = mdy(1, 1, 2011)
            set seed 2803 
            set obs `=`max' - `min' + 1'
            gen t = mdy(12, 31, 2010) + _n 
            gen doy = doy(t)
            gen isleap = !missing(mdy(2, 29, year(t)))
            format t %td 
            gen y = sin(2 * _pi * (doy - 0.5) / cond(isleap, 366, 365)) + rnormal(0, 0.01)
            
            // start here assuming that doy is a day of year variable  
            * c(Mons) contains Jan Feb ... Dec 
            tokenize "`c(Mons)'"
            forval m = 1/12  {
                local tick =  doy(mdy(`m',1, 2019)) 
                local ticks `ticks' `tick'
                local label = doy(mdy(`m', 17, 2019))
                local call `call' `label' "``m''"
            } 
            local ticks `ticks' 366 
            
            line y doy, c(L) xticks(`ticks', tlength(*3)) xla(`call', tlc(none) tlength(*0.2)) scheme(s1color) xtitle("")

            Comment


            • #7
              Thank you a lot. Although I am not a very advanced STATA user, I will try to figure out how to apply your script

              Comment


              • #8
                The main idea is in the paper referenced in #4

                We want ticks at the beginning of each month (and should remember to add a tick at 366 as 1 January in the year following a non-leap year).

                1 January tick is at day of year 1.
                1 February tick is at day of year 32.
                Thereafter it's trickier in principle because of leap years but telling apart ticks at day of year 60 or 61, and so on, is fussier than I want. So, I just loop over months and push dates 1 Jan, 1 Feb, 1 Mar, ... in a non-leap year (any such will do) through doy().

                Then we want text labels in the middle of each month and there is enough space for Jan Feb Mar ... Dec and not enough for January ... December. The three-letter abbreviations for months are stored in c(Mons) (you can thank me for that suggestion to StataCorp, although someone else would have thought of it quickly enough).

                We (surely?) don't want (to see) ticks for months too, so changing their colour to none works to ensure that. I put the labels at 17 Jan, 17 Feb, 17 Mar, ..., although you can fiddle with the position.

                tokenize is a bit of programming fal-lal to put the month labels in local macros 1 to 12 so that I can pull them out again.

                The payment due to me is to find your way (please) to https://www.statalist.org/forums/help#spelling

                The real deal is that ten years worth of these could be messy and fabplot from the Stata Journal may help there.

                Comment


                • #9
                  Thank you for your help.

                  I am sorry for asking again: why it is 2019 below?
                  forval m = 1/12 { local tick = doy(mdy(`m',1, 2019))
                  local ticks `ticks' `tick' local label = doy(mdy(`m', 17, 2019)) local call `call' `label' "``m''" }
                  local ticks `ticks' 366

                  Unfortunately I could not find out where to search for the reference you mentioned (#4)?
                  Last edited by Julia Ol; 11 Nov 2021, 03:10.

                  Comment


                  • #10
                    The reference was given in a link in post #4 of this thread. (This post is #10, and so on.)


                    Consider a day like 11 November 2021. What day of the year is it? It is day 315, and that is true in any non-leap year (one with 365 days, 28 in February).

                    Code:
                    . di doy(mdy(11, 11, 2021))
                    315
                    
                    . di doy(mdy(11, 11, 2019))
                    315
                    As said in #8 any non-leap year will do to get days of the year for deciding on tick and label positions.

                    For a leap year, positions from 1 March onwards will differ by 1. I suggest that this is too small a difference to worry about graphically.

                    Comment


                    • #11
                      I saw the pdf from the post #4

                      Just used to the reference number on the reference list. Sorry.

                      thanks for the reply.

                      Comment

                      Working...
                      X