R包出口ICS?

时间:2018-01-16 11:26:03

标签: r icalendar

是否有人知道将日期和标签导出为日历格式的R函数?

我用Google搜索并搜索过但没有什么是显而易见的,但不能相信某人还没有这样做过......

3 个答案:

答案 0 :(得分:9)

iCalendar规范为pretty straightforward。在阅读该链接后将以下扩展并将其作为参考保持方便应该是微不足道的(我故意使用该词而不是轻松地使用该词):

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

答案 1 :(得分:2)

非常感谢您之前的回答。基于此,我编写了以下函数来从磁盘或Web上读取“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

 }

答案 2 :(得分:1)

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