Does anyone know of an R function to export dates and labels to an ics calendar format?
I've googled and searched SO but nothing is obvious, but can't believe someone hasn't already done this...
Does anyone know of an R function to export dates and labels to an ics calendar format?
I've googled and searched SO but nothing is obvious, but can't believe someone hasn't already done this...
The iCalendar specification is pretty straightforward. Extending the following after reading that link and keeping it handy as a reference should be trivial (and I use that word deliberately vs lightly):
#' Create a minimal iCalendar VEVENT
#'
#' @param start,end start and end times of the event. This will be converted to
#' GMT from whatever time zone it currently is.
#' @param summary a summary of the event. This is the "title" you see in calendars.
#' @param domain something that will help the generated UUID be even more unique and
#' is generally good practice to use your org's domain name
#' @return atomic character vector ready for `writeLines()`
create_ical <- function(start, end, summary, domain="example.com") {
require(uuid, quietly = TRUE, warn.conflicts = FALSE)
sprintf(
"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//rstats//NONSGML v1.0//EN
BEGIN:VEVENT
UID:%s@%s
DTSTAMP:%s
DTSTART:%s
DTEND:%s
SUMMARY:%s
END:VEVENT
END:VCALENDAR
", uuid::UUIDgenerate(),
domain,
format(Sys.time(), "%Y%m%dT%H%M%SZ", tz="GMT"),
format(start, "%Y%m%dT%H%M%SZ", tz="GMT"),
format(end, "%Y%m%dT%H%M%SZ", tz="GMT"),
summary
)
}
Usage:
create_ical(
as.POSIXct("2018-01-30 13:00:00", origin="1970-01-01 00:00:00"),
as.POSIXct("2018-01-30 14:00:00", origin="1970-01-01 00:00:00"),
"A good description of the event",
"somedom.org"
) -> ics_event
cat(ics_event)
## BEGIN:VCALENDAR
## VERSION:2.0
## PRODID:-//rstats//NONSGML v1.0//EN
## BEGIN:VEVENT
## UID:4ae2435e-7679-495e-9377-b6da17e0090a@somedom.org
## DTSTAMP:20180116T123051Z
## DTSTART:20180130T180000Z
## DTEND:20180130T190000Z
## SUMMARY:A good description of the event
## END:VEVENT
## END:VCALENDAR
writeLines(ics_event, "ics_event.ics")
Thanks a lot for the previous answer. Based on it I write the following function to read "ics" file from disk or web.
read_google_calendar <- function(file_path) {
# 1. Read data as text lines
ics_lines <- readLines(file_path, warn = FALSE)
# 2. Disregarding value fields that have linefeeds for the sake of simplicity
stopifnot(!any(grepl("^\\s+", ics_lines)))
# 3. Parse data
key_value <- do.call(rbind, regmatches(ics_lines, regexpr(":", ics_lines, fixed = TRUE), invert = TRUE))
key_value <- key_value[which.max(key_value[ , 1] == "BEGIN" & key_value[ , 2] == "VEVENT"):tail(which(key_value[ , 1] == "END" & key_value[ , 2] == "VEVENT"), 1),]
key_value <- cbind.data.frame(key_value, id = cumsum(key_value[ , 1] == "BEGIN" & key_value[ , 2] == "VEVENT"))
# 4. Create data frame
df <- reshape(key_value, timevar = "1", idvar = "id", direction = "wide")
# 5. Change features names
colnames(df) <- c("id", "begin", "date_start", "date_end", "date_stamp",
"uid", "class", "created", "description", "last_modified",
"sequence", "status", "summary", "trans", "end")
# 6. Change features type
df <- df %>%
mutate(
date_start = as.Date(date_start, format = "%Y%m%d"),
date_end = as.Date(date_end, format = "%Y%m%d"))
# 7. Subset features
df <- df %>%
subset(select = c("date_start", "date_end", "summary", "class"))
# 8. Result
df
}