ATFutures / calendar

R interface to iCal (.ics files)
https://atfutures.github.io/calendar/
Other
41 stars 11 forks source link

Add UID for each row of dataframe #36

Open sheepworrier opened 5 years ago

sheepworrier commented 5 years ago

Great package - I'm planning to use this to generate an iCal for my team in the local snooker league. I was wondering, though, if I'm missing an easier way to generate a UID for each event in my dataframe? ic_guid just returns a character, rather than a character vector for all rows in the dataframe, so I had to add a user defined function as below:

my_fixtures <- fixtures %>%
  filter(home_team == my_team | away_team == my_team) %>%
  mutate(SUMMARY = ifelse(home_team == my_team,
                          paste(away_team, "(H)"),
                          paste(home_team, "(A)")),
         DTSTART = as_datetime(dmy_hms(paste(date, time))),
         DTEND = as_datetime(ymd_hms(DTSTART) + hours(3)),
         LOCATION = venue) %>%
  select(SUMMARY, DTSTART, DTEND, LOCATION)

add_uid <- function(SUMMARY, DTSTART, DTEND, LOCATION) {
  data.frame(UID = ic_guid(),
             SUMMARY = SUMMARY,
             DTSTART = DTSTART,
             DTEND = DTEND,
             LOCATION = LOCATION,
             stringsAsFactors = FALSE)
}

my_fixtures <- pmap_dfr(my_fixtures, add_uid)

ic <- ical(my_fixtures)
ic_write(ic, "my_fixtures.ics")
Robinlovelace commented 5 years ago

Fantastic to hear you're using it @sheepworrier ! Could you create a reproducible example? Thoughts @layik (who wrote the uid code)?

sheepworrier commented 5 years ago

Sorry, should have done that to start with - here goes with my first ever reprex...

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:lubridate':
#> 
#>     intersect, setdiff, union
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(calendar)
fixtures <-
  data.frame(SUMMARY = paste("Match", seq(1, 3)),
             DTSTART = ymd_hms("2019-05-13 13:51:50"),
             DTEND = ymd_hms("2019-05-13 17:51:50"),
             LOCATION = paste("Venue", seq(1, 3)),
             stringsAsFactors = FALSE)

fixtures %>%
  mutate(UID = ic_guid())
#>   SUMMARY             DTSTART               DTEND LOCATION
#> 1 Match 1 2019-05-13 13:51:50 2019-05-13 17:51:50  Venue 1
#> 2 Match 2 2019-05-13 13:51:50 2019-05-13 17:51:50  Venue 2
#> 3 Match 3 2019-05-13 13:51:50 2019-05-13 17:51:50  Venue 3
#>                                         UID
#> 1 ical-09f692c7-8663-4fc4-9f78-1affc97d8ca9
#> 2 ical-09f692c7-8663-4fc4-9f78-1affc97d8ca9
#> 3 ical-09f692c7-8663-4fc4-9f78-1affc97d8ca9

Created on 2019-05-13 by the reprex package (v0.2.1)

I would expect ic_guid() to generate a different unique ID for each row in the dataframe. Not a fault per se, but a suggestion for improvement / request for the correct syntax I should use?

sheepworrier commented 5 years ago

I think I've worked it out for myself from this thread. I need to use replicate() to get a unique UID per row:

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:lubridate':
#> 
#>     intersect, setdiff, union
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(calendar)
fixtures <-
  data.frame(SUMMARY = paste("Match", seq(1, 3)),
             DTSTART = ymd_hms("2019-05-13 13:51:50"),
             DTEND = ymd_hms("2019-05-13 17:51:50"),
             LOCATION = paste("Venue", seq(1, 3)),
             stringsAsFactors = FALSE)

fixtures %>%
  mutate(UID = replicate(nrow(fixtures), ic_guid()))
#>   SUMMARY             DTSTART               DTEND LOCATION
#> 1 Match 1 2019-05-13 13:51:50 2019-05-13 17:51:50  Venue 1
#> 2 Match 2 2019-05-13 13:51:50 2019-05-13 17:51:50  Venue 2
#> 3 Match 3 2019-05-13 13:51:50 2019-05-13 17:51:50  Venue 3
#>                                         UID
#> 1 ical-fe0cbc33-f370-471f-aa0a-bb47361194ad
#> 2 ical-1bcf178e-fd26-4007-86cb-6f2ae5b5f72a
#> 3 ical-cbbe6849-3662-4e14-915d-ef797f345503

Created on 2019-05-13 by the reprex package (v0.2.1)

Robinlovelace commented 5 years ago

Great work. It should be easier than that though, so keeping open. Many thanks for the reprex.

layik commented 5 years ago

@sheepworrier great to know you are using it. Apologies for lack of reply here.

I think the reason is that you were not using ic_event to create each row? Am I right? Otherwise if we were to use the fixtures using the ic_event then it should call ic_guid to make your life easier.

When I have some time, I will definitely double check this.

sheepworrier commented 5 years ago

Thanks for all your work on the package - very helpful!

Yes that’s right. I was following along using the code in one of the earlier issues that was going to become a vignette. After creating the dataframe above I then run something like:

ic <- ical(fixtures)
ic_write(ic, "fixtures.ics"))

This executed without error but then Google only imports a single event due to the duplicate UID.