R言語 - CalDAVカレンダーを操作する

# はじめに
　CalDAV とは、スケジュールの標準インターフェースで、iCalendar をベースとしています。これは RFC 5545 で規定されており、PIM(Personal Information Management)データ標準のカレンダー管理を行うことができます。サンプルデータは次の通りです。CalDAVインターフェイスのあるカレンダーであれば、当然のことながら、R 環境からのアクセスが可能です。

▼サンプルデータ

```R:MyCalendar.ics(サンプルデータ)
BEGIN:VCALENDAR
X-PUBLISHED-TTL:PT180M
CALSCALE:GREGORIAN
VERSION:2.0
PRODID:-//ENTERPRISE//NONSGML Time Management - //EN
X-ENTERPRISE-ID:334B:3BF0:ints:38893C00F42F38A1E0404498C8A6612B000B4D88B0C1
X-ENTERPRISE-ETAG:14240338735482
BEGIN:VEVENT
DTEND;TZID=Asia/Tokyo:20150715T173000
CLASS:CONFIDENTIAL
SUMMARY:ABC Project Report Meeting
ATTENDEE;PARTSTAT=ACCEPTED;RSVP=FALSE;CN=John Smith;CUTYPE=INDIVIDU
 AL;X-ENTERPRISE-TRANSP=OPAQUE:mailto:John.Smith@enterprise.com
PRIORITY:0
DTSTAMP:20150708T014124Z
X-ENTERPRISE-EVENTTYPE:APPOINTMENT
SEQUENCE:0
X-ENTERPRISE-CLASS:NORMAL
UID:uid-38893C00F42F38A1E0404498C8A6612B000B4D88B0BF
STATUS:CONFIRMED
DTSTART;TZID=Asia/Tokyo:20150715T160000
LAST-MODIFIED:20150708T014124Z
TRANSP:OPAQUE
ORGANIZER;CN=John Smith:mailto:John.Smith@enterprise.com
X-ENTERPRISE-ID:334B:3BF0:invt:38893C00F42F38A1E0404498C8A6612B000B4D88B0C2
DESCRIPTION:
CREATED:20150708T014050Z
END:VEVENT
BEGIN:VTIMEZONE
LAST-MODIFIED:20141227T085509Z
TZID:Asia/Tokyo
X-ENTERPRISE-ID:334B:3BF0:tmzn:38893C00F42F38A1E0404498C8A6612B0000000003CC
BEGIN:STANDARD
TZOFFSETFROM:+1000
TZOFFSETTO:+0900
DTSTART:19900908T020000
RDATE:19900908T020000
TZNAME:JST
END:STANDARD
END:VTIMEZONE
END:VCALENDAR
```

# 文字列操作に便利な関数の宣言
```R:R
# カレンダー・イベントの時間を求める関数を宣言します
# 引数dは、日付に変換したい文字列(例：20150109T093000)
eventTime <- function( d ){paste(paste(substr( d, 1, 4 ),
                           substr( d, 5, 6 ), substr( d, 7, 8 ), sep = "-"), 
                           paste( substr( d, 10, 11 ),substr( d, 12, 13 ), sep = ":" ))
                          }
# 対象文字列から区切り文字以降の文字列を切り出す関数を宣言します
# 引数は、a:対象文字列、b:区切り文字、c:調整文字数 
cutWord <- function( a, b, c ){substr( a, regexpr( b, a )[1] + c, nchar( a ))}
```

# カレンダーからイベント情報の抽出
　カレンダーから、イベントの開始時間、イベント終了時間、イベント名称、イベント作成者、イベント所要時間の情報を抽出します。

▼サンプルスクリプト

```R:R
# 作業ディレクトリの指定
setwd("working_dir")
# カレンダーファイルのエイリアス
fileMyCal <- "MyCalendar.ics"
# ファイル読み込みモード
modeRead  <- "r"
# ファイル読み込み
txtCalBuf <- file( fileMyCal, modeRead )
# テキスト読み込み
txtCalTxt <- as.list( readLines( txtCalBuf ))
# ファイルクローズ
close( txtCalBuf )
# イベント用データフレーム
tabEvent <- data.frame( 0, 0, 0, 0, 0 )
# 一時イベント用データフレーム
tmpEvent <- data.frame( 0, 0, 0, 0, 0 )
# イベント開始フラグ(1:イベント開始)
flgBeginEvent <- 0
# 終日イベントフラグ(1:終日イベント)
flgDayEvent <- 0
for ( i in 1:length( txtCalTxt )){
  # イベントの開始 ※イベント開始フラグを立てる
  if ( length( grep( "^BEGIN:VEVENT", txtCalTxt[i] )) > 0 ){ flgBeginEvent <- 1; next }
  # イベント開始日時(例：20150109T093000)
  if ( length( grep( "DTSTART", txtCalTxt[i] )) > 0 && flgBeginEvent == 1 )
  { tmpEvent[1,1] <- cutWord(txtCalTxt[i], ":", 1); next}
  # イベント終了日時(例：20150109T093000)
  if ( length( grep( "DTEND", txtCalTxt[i] )) > 0 && flgBeginEvent == 1 )
  { tmpEvent[1,2] <- cutWord(txtCalTxt[i], ":", 1); next}
  # イベント名称
  if ( length( grep( "^SUMMARY", txtCalTxt[i] )) > 0 && flgBeginEvent == 1 )
  { tmpEvent[1,3] <- cutWord(txtCalTxt[i], ":", 1); next}
  # イベント立案者の情報
  if ( length( grep( "^ORGANIZER", txtCalTxt[i] )) > 0 && flgBeginEvent == 1 )
  { tmpEvent[1,4] <- cutWord(txtCalTxt[i], "mailto", 7); next}
  # 一日分のイベント ※除外するためフラグを立てる
  if ( txtCalTxt[i]=="X-ENTERPRISE-EVENTTYPE:DAY_EVENT"  && flgBeginEvent == 1 )
  { flgDayEvent <- 1; next }
  # イベントの終了
  if ( length( grep( "^END:VEVENT", txtCalTxt[i] )) > 0 ){
    # 一日分のイベントがフラグオフの場合、データをバインドする
    if ( flgDayEvent != 1 ){
      tmpEvent[1,5] <- difftime( eventTime( tmpEvent[1,2] ), eventTime( tmpEvent[1,1] ), units="mins" )
      tabEvent <- rbind( tabEvent, tmpEvent )
    } else { flgDayEvent <- 0 }
    flgBeginEvent <- 0
  }
}
# イベント開始日時の昇順で並び変える
sortlist <-order(tabEvent[,1],decreasing = FALSE)
tabEvent2 <-tabEvent[sortlist,]
# 列名を追加する
colnames(tabEvent2) <- c("start", "end", "summary", "organizer", "time")
```

▼実行結果例

```R:実行結果例
> tabEvent2
            start             end                    summary                 organizer time
1               0               0                          0                         0    0
2 20150715T160000 20150715T173000 ABC Project Report Meeting John.Smith@enterprise.com   90
> 

```

# さいごに
　CalDAVカレンダーをデータフレームの形にできれば、ここから先は統計解析をするだけです。どのような統計解析ができるかというと、例えば、このカレンダー情報を使って、優秀な人の行動プロファイルを分析するといったことができると思います。


# リファレンス
iCalendar
https://ja.wikipedia.org/wiki/ICalendar
Internet Calendaring and Scheduling Core Object Specification
http://www.rfc-editor.org/rfc/rfc5545.txt