用于导出 ICS 的 R 包?

R package to export ICS?

有谁知道可以将日期和标签导出为 ics 日历格式的 R 函数吗?

我用谷歌搜索了 SO 但没有什么是显而易见的,但不敢相信有人还没有这样做...

iCalendar 规范是 pretty straightforward。在阅读 link 并将其作为参考 后扩展以下 应该是微不足道的(我故意使用这个词而不是轻率地使用):

#' 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
)
  
}

用法:

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")

非常感谢前面的回答。基于它,我编写了以下函数来从磁盘或网络读取 "ics" 文件。

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

 }

虽然上面发布的解决方案效果很好,但另一个选择是 CRAN 上的 calendar 包(文档 here)。从 ICS 文件导入数据框只需要一行代码,创建新事件然后导出到新的 ICS 文件也很简单。