title: Are there more elegant ways to transform ragged data into a tidy dataframe
body: <p>I have a dataframe that contains a column of ragged data: "topics" where each topic is a string of characters, and adjacent topics are separated from each other by a delimiter ("|" in this case):</p>
  
  <pre><code>library(lubridate)
  events &lt;- data.frame(
    date  =dmy(c(     "12/6/2012",           "13/7/2012",    "4/8/2012")),
    days  =    c(               1,                     6,           0.5),
    name  =    c("Intro to stats", "Stats Winter school", "TidyR tools"),
    topics=    c( "probability|R", "R|regression|ggplot", "tidyR|dplyr"),
    stringsAsFactors=FALSE
    )
  </code></pre>
  
  <p>The <code>events</code> dataframe looks like:</p>
  
  <pre><code>        date days                name              topics
  1 2012-06-12  1.0      Intro to stats       probability|R
  2 2012-07-13  6.0 Stats Winter school R|regression|ggplot
  3 2012-08-04  0.5         TidyR tools         tidyR|dplyr
  </code></pre>
  
  <p>I want to transform this dataframe so that each row contains a single topic, and an indication of how many days were spent on that topic, assuming that if N topics were presented over D days, D/N days were spent on each topic.</p>
  
  <p>I had to do this in a hurry, and did so as follows:</p>
  
  <pre><code>library(dplyr)
  
  events %&gt;%
    # Figure out how many topics were delivered at each event
    mutate(
      ntopics=sapply(
        gregexpr("|", topics, fixed=TRUE),
        function(x)(1 + sum(attr(x, "match.length") &gt; 0 ))
        )
      ) %&gt;%
    # Create a data frame with one topic per row
    do(data.frame(
      date    =rep(   .$date, .$ntopics),
      days    =rep(   .$days, .$ntopics),
      name    =rep(   .$name, .$ntopics),
      ntopics =rep(.$ntopics, .$ntopics),
      topic   =unlist(strsplit(.$topics, "|", fixed=TRUE)),
      stringsAsFactors=FALSE
      )) %&gt;%
    # Estimate roughly how many days were spent on each topic
    mutate(daysPerTopic=days/ntopics)
  </code></pre>
  
  <p>which gives us</p>
  
  <pre><code>        date days                name ntopics       topic daysPerTopic
  1 2012-06-12  1.0      Intro to stats       2 probability         0.50
  2 2012-06-12  1.0      Intro to stats       2           R         0.50
  3 2012-07-13  6.0 Stats Winter school       3           R         2.00
  4 2012-07-13  6.0 Stats Winter school       3  regression         2.00
  5 2012-07-13  6.0 Stats Winter school       3      ggplot         2.00
  6 2012-08-04  0.5         TidyR tools       2       tidyR         0.25
  7 2012-08-04  0.5         TidyR tools       2       dplyr         0.25
  </code></pre>
  
  <p>I would love to know how do achieve this more elegantly.</p>