Use base R functions to label a date vector

Suppose you want to label a date vector with their relevant month, day of week, quarter, or days since a certain date (for example deadlines), how will you go about doing this?

from this:

[1] "1950-11-12" "1980-04-30"
[3] "2010-08-22" "2029-07-01"

to this:

  Q4|Sun|Nov   Q2|Wed|Apr   Q3|Sun|Aug 
"1950-11-12" "1980-04-30" "2010-08-22" 
  Q3|Sun|Jul 
"2029-07-01" 

or just day of week:

      Sunday    Wednesday       Sunday 
"1950-11-12" "1980-04-30" "2010-08-22" 
      Sunday 
"2029-07-01" 


First create a date vector a1:

a1 <- c("1969-09-26", "1970-05-08")

Check it out:

a1
[1] "1969-09-26" "1970-05-08"

label the vector

we can create vector v1 to name vector a01:

a01 <- a1
v1 <- c("the start", "the end")
names(a01) <- v1
a01
   the start      the end 
"1969-09-26" "1970-05-08" 

or create a separate vector:

a0 <- a1
names(a0) <- c("birthdate", 007)
a0
   birthdate            7 
"1969-09-26" "1970-05-08" 

what happens if we name it with a vector of a different length?

a02 <- a1
names(a02) <- c(5:7) 
Error in names(a02) <- c(5:7) : 
  'names' attribute [3] must be the same length as the vector [2]

you get told off! *** ## using dates let’s try to name this using months!

names(a1) <- months(a1)
Error in UseMethod("months") : 
  no applicable method for 'months' applied to an object of class "character"

seems that we didn’t actually create a date vector! Double check:

class(a1)
[1] "character"

convert vector to date

a2 <- as.Date(a1)

print & check class:

a2
[1] "1969-09-26" "1970-05-08"
class(a2)
[1] "Date"

Now that we actually have a date vector, we can name the items! ## Labeling by date {.tabset}

label by month

names(a2) <- months(a2)
a2
   September          May 
"1969-09-26" "1970-05-08" 

label by week

a3 <- a2
names(a3) <- weekdays(a3)
a3
      Friday       Friday 
"1969-09-26" "1970-05-08" 

label by year?

a4 <- a2
names(a4) <- years(a4)
Error in years(a4) : could not find function "years"

We get an error, as there is no year function in R base function for time (POSIXt or Date Object). We will get to this later. For now, let’s focus on what we do have: weekdays, months, quarters, & julian (returns numbers of days since the origin).

label by quarters

a5 <- a2
names(a5) <- quarters(a5)
a5
          Q3           Q2 
"1969-09-26" "1970-05-08" 

“julian” - calculate days since

a6 <- a2
names(a6) <- julian(a6)
a6
         -97          127 
"1969-09-26" "1970-05-08" 

Seems that this is calculating days from a date between these two dates. What is going on here? Apparently it’s calculated based on an origin date.

what is the origin date here?

?as.POSIXct

typing the above gives R documentation for a base function, which notes that the origin date in R is ‘1970-01-01 00:00.00 UTC’. ref

Can we specify the origin date?
a7 <- a2
names(a7) <- julian(a7, origin = as.Date("1900-01-01"))
a7
       25470        25694 
"1969-09-26" "1970-05-08" 

note that we cannot change the default origin, but must specify when using. Let’s see what happens when we don’t specify:

a8 <- a7
names(a8) <- julian(a8)
a8
         -97          127 
"1969-09-26" "1970-05-08" 

All together now

a9 <- a2
names(a9) <- paste(months(a9),weekdays(a9), quarters(a9), sep = "/") #default separator is blank space
a9
September/Friday/Q3 
       "1969-09-26" 
      May/Friday/Q2 
       "1970-05-08" 

This seems rather long, can we abbreviate it?

a10 <- a2
names(a10) <- paste(months(a9, abbreviate = TRUE), weekdays(a9, abbreviate = TRUE), quarters(a9), sep = "-") #as default abbreviate is set to FALSE
a10
  Sep-Fri-Q3   May-Fri-Q2 
"1969-09-26" "1970-05-08" 

I didn’t abbreviate quarters as it can’t get shorter. Note that I just reused a9. Using a vector for labelling does not change the vector itself, as you can see below:

a9
September/Friday/Q3 
       "1969-09-26" 
      May/Friday/Q2 
       "1970-05-08" 

if I names(a9) anew, the new name will overwrite previous name.


Label with year

To extract the year as a label, we can first extract the year using format(), & then label the vector.

a11 <- a2
v11 <- format(a2, format="%Y")

names(a11) <- v11
a11
        1969         1970 
"1969-09-26" "1970-05-08" 

Et voila. A small exercise.
What else can you do with this?

LS0tCnRpdGxlOiAiTGFiZWwgbW9udGgsIHdlZWssIG9yIHF1YXJ0ZXIgb2YgYSBkYXRlIHZlY3RvciB1c2luZyBiYXNlIFIgZnVuY3Rpb25zIgphdXRob3I6ICJHcmFjZSBCeXJuZSIKZGF0ZTogMjAyMi0xMC0yNApvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgdGhlbWU6IHNwYWNlbGFiCiAgICBoaWdobGlnaHQ6IGVzcHJlc3NvCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA1CiAgICAjIHRvY19mbG9hdDogdHJ1ZSAjZm9yIHRhYmxlIG9mIGNvbnRlbnRzIHRvIGZsb2F0IG9uIGxlZnQgc2lkZS4KICAgICMgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKLS0tCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCioqVXNlIGJhc2UgUiBmdW5jdGlvbnMgdG8gbGFiZWwgYSBkYXRlIHZlY3RvcioqICAKClN1cHBvc2UgeW91IHdhbnQgdG8gbGFiZWwgYSBkYXRlIHZlY3RvciB3aXRoIHRoZWlyIHJlbGV2YW50IG1vbnRoLCBkYXkgb2Ygd2VlaywgcXVhcnRlciwgb3IgZGF5cyBzaW5jZSBhIGNlcnRhaW4gZGF0ZSAoZm9yIGV4YW1wbGUgZGVhZGxpbmVzKSwgaG93IHdpbGwgeW91IGdvIGFib3V0IGRvaW5nIHRoaXM/Cgpmcm9tIHRoaXM6CmBgYHtyLCBlY2hvID0gRkFMU0V9CmEgPC0gYXMuRGF0ZShjKCIxOTUwLTExLTEyIiwgIjE5ODAtMDQtMzAiLCAiMjAxMC0wOC0yMiIsICIyMDI5LTA3LTAxIikpCmEKYGBgCgoKdG8gdGhpczoKYGBge3IsIGVjaG8gPSBGQUxTRX0KbmFtZXMoYSkgPC0gcGFzdGUocXVhcnRlcnMoYSksIHdlZWtkYXlzKGEsIGFiYnJldmlhdGUgPSBUUlVFKSwgbW9udGhzKGEsIGFiYnJldmlhdGUgPSBUUlVFKSwgc2VwID0gInwiKQoKYQpgYGAKCm9yIGp1c3QgZGF5IG9mIHdlZWs6CmBgYHtyLCBlY2hvID0gRkFMU0V9CmEwMDEgPC0gYQpuYW1lcyhhMDAxKSA8LSB3ZWVrZGF5cyhhKQoKYTAwMQpgYGAKKioqICAKKioqICAKRmlyc3QgY3JlYXRlIGEgZGF0ZSB2ZWN0b3IgYGExYDoKYGBge3J9CmExIDwtIGMoIjE5NjktMDktMjYiLCAiMTk3MC0wNS0wOCIpCmBgYApDaGVjayBpdCBvdXQ6CmBgYHtyfQphMQpgYGAKCiMjIyMgbGFiZWwgdGhlIHZlY3RvciAKd2UgY2FuIGNyZWF0ZSB2ZWN0b3IgYHYxYCB0byBuYW1lIHZlY3RvciBgYTAxYDoKYGBge3J9CmEwMSA8LSBhMQp2MSA8LSBjKCJ0aGUgc3RhcnQiLCAidGhlIGVuZCIpCm5hbWVzKGEwMSkgPC0gdjEKYTAxCmBgYApvciBjcmVhdGUgYSBzZXBhcmF0ZSB2ZWN0b3I6CmBgYHtyfQphMCA8LSBhMQpuYW1lcyhhMCkgPC0gYygiYmlydGhkYXRlIiwgMDA3KQphMApgYGAKd2hhdCBoYXBwZW5zIGlmIHdlIG5hbWUgaXQgd2l0aCBhIHZlY3RvciBvZiBhIGRpZmZlcmVudCBsZW5ndGg/CmBgYHtyfQphMDIgPC0gYTEKbmFtZXMoYTAyKSA8LSBjKDU6NykgCmEwMgpgYGAKeW91IGdldCB0b2xkIG9mZiEKKioqCiMjIHVzaW5nIGRhdGVzCmxldCdzIHRyeSB0byBuYW1lIHRoaXMgdXNpbmcgbW9udGhzIQoKYGBge3J9Cm5hbWVzKGExKSA8LSBtb250aHMoYTEpCmBgYApzZWVtcyB0aGF0IHdlIGRpZG4ndCBhY3R1YWxseSBjcmVhdGUgYSBkYXRlIHZlY3RvciEgRG91YmxlIGNoZWNrOgpgYGB7cn0KY2xhc3MoYTEpCmBgYAoqKioKIyMjIyBjb252ZXJ0IHZlY3RvciB0byBkYXRlCmBgYHtyfQphMiA8LSBhcy5EYXRlKGExKQpgYGAKcHJpbnQgJiBjaGVjayBjbGFzczoKYGBge3J9CmEyCmNsYXNzKGEyKQpgYGAKTm93IHRoYXQgd2UgYWN0dWFsbHkgaGF2ZSBhIGRhdGUgdmVjdG9yLCB3ZSBjYW4gbmFtZSB0aGUgaXRlbXMhCiMjIExhYmVsaW5nIGJ5IGRhdGUgey50YWJzZXR9CgojIyMgbGFiZWwgYnkgbW9udGgKYGBge3J9Cm5hbWVzKGEyKSA8LSBtb250aHMoYTIpCmEyCmBgYAoKIyMjIGxhYmVsIGJ5IHdlZWsKCmBgYHtyfQphMyA8LSBhMgpuYW1lcyhhMykgPC0gd2Vla2RheXMoYTMpCmEzCmBgYAoKIyMjIGxhYmVsIGJ5IHllYXI/CgpgYGB7cn0KYTQgPC0gYTIKbmFtZXMoYTQpIDwtIHllYXJzKGE0KQphNApgYGAKV2UgZ2V0IGFuIGVycm9yLCBhcyB0aGVyZSBpcyBubyB5ZWFyIGZ1bmN0aW9uIGluIFtSIGJhc2UgZnVuY3Rpb24gZm9yIHRpbWUgKFBPU0lYdCBvciBEYXRlIE9iamVjdCldKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9iYXNlL3ZlcnNpb25zLzMuNi4yL3RvcGljcy93ZWVrZGF5cykuIFdlIHdpbGwgZ2V0IHRvIHRoaXMgbGF0ZXIuIEZvciBub3csIGxldCdzIGZvY3VzIG9uIHdoYXQgd2UgZG8gaGF2ZTogYHdlZWtkYXlzYCwgYG1vbnRoc2AsIGBxdWFydGVyc2AsICYgYGp1bGlhbmAgKHJldHVybnMgbnVtYmVycyBvZiBkYXlzIHNpbmNlIHRoZSBvcmlnaW4pLgoKIyMjIGxhYmVsIGJ5IHF1YXJ0ZXJzCgpgYGB7cn0KYTUgPC0gYTIKbmFtZXMoYTUpIDwtIHF1YXJ0ZXJzKGE1KQphNQpgYGAKCiMjIyAianVsaWFuIiAtIGNhbGN1bGF0ZSBkYXlzIHNpbmNlCgpgYGB7cn0KYTYgPC0gYTIKbmFtZXMoYTYpIDwtIGp1bGlhbihhNikKYTYKYGBgClNlZW1zIHRoYXQgdGhpcyBpcyBjYWxjdWxhdGluZyBkYXlzIGZyb20gYSBkYXRlIGJldHdlZW4gdGhlc2UgdHdvIGRhdGVzLiBXaGF0IGlzIGdvaW5nIG9uIGhlcmU/IEFwcGFyZW50bHkgaXQncyBjYWxjdWxhdGVkIGJhc2VkIG9uIGFuICoqb3JpZ2luIGRhdGUqKi4KCiMjIyMgd2hhdCBpcyB0aGUgb3JpZ2luIGRhdGUgaGVyZT8KCmBgYHtyfQo/YXMuUE9TSVhjdApgYGAKCnR5cGluZyB0aGUgYWJvdmUgZ2l2ZXMgUiBkb2N1bWVudGF0aW9uIGZvciBhIGJhc2UgZnVuY3Rpb24sIHdoaWNoIG5vdGVzIHRoYXQgdGhlIG9yaWdpbiBkYXRlIGluIFIgaXMgJzE5NzAtMDEtMDEgMDA6MDAuMDAgVVRDJy4gW3JlZl0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2Jhc2UvdmVyc2lvbnMvMy42LjIvdG9waWNzL0lTT2RhdGV0aW1lKQoKIyMjIyMgQ2FuIHdlIHNwZWNpZnkgdGhlIG9yaWdpbiBkYXRlPwoKYGBge3J9CmE3IDwtIGEyCm5hbWVzKGE3KSA8LSBqdWxpYW4oYTcsIG9yaWdpbiA9IGFzLkRhdGUoIjE5MDAtMDEtMDEiKSkKYTcKYGBgCgpfX25vdGVfXyB0aGF0IHdlIGNhbm5vdCBjaGFuZ2UgdGhlIGRlZmF1bHQgb3JpZ2luLCBidXQgbXVzdCBzcGVjaWZ5IHdoZW4gdXNpbmcuIExldCdzIHNlZSB3aGF0IGhhcHBlbnMgd2hlbiB3ZSBkb24ndCBzcGVjaWZ5OgoKYGBge3J9CmE4IDwtIGE3Cm5hbWVzKGE4KSA8LSBqdWxpYW4oYTgpCmE4CmBgYAoKKioqICAKIyMgQWxsIHRvZ2V0aGVyIG5vdwoKYGBge3J9CmE5IDwtIGEyCm5hbWVzKGE5KSA8LSBwYXN0ZShtb250aHMoYTkpLHdlZWtkYXlzKGE5KSwgcXVhcnRlcnMoYTkpLCBzZXAgPSAiLyIpICNkZWZhdWx0IHNlcGFyYXRvciBpcyBibGFuayBzcGFjZQphOQpgYGAKClRoaXMgc2VlbXMgcmF0aGVyIGxvbmcsIGNhbiB3ZSBhYmJyZXZpYXRlIGl0PwoKYGBge3J9CmExMCA8LSBhMgpuYW1lcyhhMTApIDwtIHBhc3RlKG1vbnRocyhhOSwgYWJicmV2aWF0ZSA9IFRSVUUpLCB3ZWVrZGF5cyhhOSwgYWJicmV2aWF0ZSA9IFRSVUUpLCBxdWFydGVycyhhOSksIHNlcCA9ICItIikgI2FzIGRlZmF1bHQgYWJicmV2aWF0ZSBpcyBzZXQgdG8gRkFMU0UKYTEwCmBgYAoKSSBkaWRuJ3QgYWJicmV2aWF0ZSBxdWFydGVycyBhcyBpdCBjYW4ndCBnZXQgc2hvcnRlci4gTm90ZSB0aGF0IEkganVzdCByZXVzZWQgYTkuIFVzaW5nIGEgdmVjdG9yIGZvciBsYWJlbGxpbmcgZG9lcyBub3QgY2hhbmdlIHRoZSB2ZWN0b3IgaXRzZWxmLCBhcyB5b3UgY2FuIHNlZSBiZWxvdzoKCmBgYHtyfQphOQpgYGAKCmlmIEkgYG5hbWVzKGE5KWAgYW5ldywgdGhlIG5ldyBuYW1lIHdpbGwgb3ZlcndyaXRlIHByZXZpb3VzIG5hbWUuCgoqKiogIAojIyMgTGFiZWwgd2l0aCB5ZWFyClRvIGV4dHJhY3QgdGhlIHllYXIgYXMgYSBsYWJlbCwgd2UgY2FuIGZpcnN0IGV4dHJhY3QgdGhlIHllYXIgdXNpbmcgYGZvcm1hdCgpYCwgJiB0aGVuIGxhYmVsIHRoZSB2ZWN0b3IuCmBgYHtyfQphMTEgPC0gYTIKdjExIDwtIGZvcm1hdChhMiwgZm9ybWF0PSIlWSIpCgpuYW1lcyhhMTEpIDwtIHYxMQphMTEKYGBgCgpFdCB2b2lsYS4gQSBzbWFsbCBleGVyY2lzZS4gICAKV2hhdCBlbHNlIGNhbiB5b3UgZG8gd2l0aCB0aGlzPw==