A tribute to Lucy D’Agostino McGowan’s git commit emoji game

[This article was first published on Maëlle, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Do you know Lucy? She is a very talented biostatistics PhD candidate that I had the chance to e-meet thanks to R-Ladies. One maybe superficial reason to admire her, on top of her other achievements, is her emoji game in git commits. Looking at Lucy’s git history (find her on Github), one wants to start using version control because she makes it look fun!

In this post, I will download many git commit messages of Lucy’s from Github’s API via the gh package, and have a look at the emojis she uses the most frequently.

Getting the commit messages

As I said I’ll use the gh package as in my post about first commits and as in the one about random seeds.

The first step is to get the names of Lucy’s repositories. I get all her public repositories, and also a few of the repositories of the LFOD organization where she blogs, that I selected by hand for not getting forks from the public repositories I already had. Hopefully her commit messages in these repositories, obviously excluding her private repositories, is representative of her typical emoji use.

<span class="n">library</span><span class="p">(</span><span class="s2">"gh"</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="s2">"magrittr"</span><span class="p">)</span><span class="w">
</span><span class="n">lucy_repos</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">gh</span><span class="p">(</span><span class="s2">"/users/:username/repos"</span><span class="p">,</span><span class="w"> 
                 </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"public"</span><span class="p">,</span><span class="w"> 
                 </span><span class="n">username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"LucyMcGowan"</span><span class="p">)</span><span class="w">
</span><span class="n">lucy_repos</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">vapply</span><span class="p">(</span><span class="n">lucy_repos</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">)</span><span class="w">
</span><span class="n">lucy_repos</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">tibble</span><span class="o">::</span><span class="n">tibble</span><span class="p">(</span><span class="n">repos</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lucy_repos</span><span class="p">,</span><span class="w">
                             </span><span class="n">who</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"LucyMcGowan"</span><span class="p">)</span><span class="w">
</span><span class="n">lucy_repos_org</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">tibble</span><span class="o">::</span><span class="n">tibble</span><span class="p">(</span><span class="n">repos</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"LFOD.github.io"</span><span class="p">,</span><span class="w">
                                           </span><span class="s2">"blog"</span><span class="p">,</span><span class="w">
                                           </span><span class="s2">"real-blog"</span><span class="p">),</span><span class="w">
                                 </span><span class="n">who</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"LFOD"</span><span class="p">)</span><span class="w">

</span><span class="n">lucy_repos</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">dplyr</span><span class="o">::</span><span class="n">bind_rows</span><span class="p">(</span><span class="n">lucy_repos</span><span class="p">,</span><span class="w">
                               </span><span class="n">lucy_repos_org</span><span class="p">)</span><span class="w">

</span><span class="n">head</span><span class="p">(</span><span class="n">lucy_repos</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">knitr</span><span class="o">::</span><span class="n">kable</span><span class="p">()</span><span class="w">
</span>
repos who
2017-03-18_hackathon LucyMcGowan
branchingExample LucyMcGowan
comps-survival-guide LucyMcGowan
contributr LucyMcGowan
cowsay LucyMcGowan
datasauRus LucyMcGowan

Then I got the commit messages, but also their authors in order to filter commits by Lucy herself, and the time and date at which they were made because Lucy told me she started using emojis last October. gh is a minimal package so it outputs lists of lists, so each time I use it I have a look at their structure to find how to extract exactly what I need, see below.

<span class="n">get_all_lucy_commits</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span><span class="w"> </span><span class="n">who</span><span class="p">){</span><span class="w">
  
  </span><span class="c1"># Since I don't know the number of pages</span><span class="w">
  </span><span class="c1"># I grow the vectors of messages, dates and authors</span><span class="w">
  </span><span class="n">messages</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
  </span><span class="n">authors</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
  </span><span class="n">dates</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
  
  </span><span class="n">page</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="m">1</span><span class="w">
  </span><span class="n">is_still_ok</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="kc">TRUE</span><span class="w">
  </span><span class="c1"># loop while page still full of content</span><span class="w">
  </span><span class="k">while</span><span class="p">(</span><span class="n">is_still_ok</span><span class="p">[</span><span class="m">1</span><span class="p">]){</span><span class="w">
    </span><span class="n">commits</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">try</span><span class="p">(</span><span class="n">gh</span><span class="p">(</span><span class="s2">"/repos/:owner/:repo/commits"</span><span class="p">,</span><span class="w">
                      </span><span class="n">owner</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">who</span><span class="p">,</span><span class="w">
                      </span><span class="n">repo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">repo</span><span class="p">,</span><span class="w">
                      </span><span class="n">page</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">page</span><span class="p">))</span><span class="w">
    
    </span><span class="k">if</span><span class="p">(</span><span class="nf">class</span><span class="p">(</span><span class="n">commits</span><span class="p">)[</span><span class="m">1</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s2">"try-error"</span><span class="p">){</span><span class="w">
      </span><span class="n">is_still_ok</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">commits</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s2">""</span><span class="w">
    </span><span class="p">}</span><span class="k">else</span><span class="p">{</span><span class="w">
      </span><span class="n">is_still_ok</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="kc">FALSE</span><span class="w">
    </span><span class="p">}</span><span class="w">
    
    </span><span class="k">if</span><span class="p">(</span><span class="n">is_still_ok</span><span class="p">[</span><span class="m">1</span><span class="p">]){</span><span class="w">
      </span><span class="c1"># get information about commits</span><span class="w">
      </span><span class="n">commit_info</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">lapply</span><span class="p">(</span><span class="n">commits</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">"commit"</span><span class="p">)</span><span class="w">
      
      </span><span class="c1"># commit messages</span><span class="w">
      </span><span class="n">now_messages</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">lapply</span><span class="p">(</span><span class="n">commit_info</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">"message"</span><span class="p">)</span><span class="w">
      </span><span class="n">messages</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="n">messages</span><span class="p">,</span><span class="w"> </span><span class="n">unlist</span><span class="p">(</span><span class="n">now_messages</span><span class="p">))</span><span class="w">
      
      </span><span class="c1"># date (and time)</span><span class="w">
      </span><span class="n">committer</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">lapply</span><span class="p">(</span><span class="n">commit_info</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">"committer"</span><span class="p">)</span><span class="w">
      </span><span class="n">now_dates</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">lapply</span><span class="p">(</span><span class="n">committer</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">"date"</span><span class="p">)</span><span class="w">
      </span><span class="n">dates</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="n">dates</span><span class="p">,</span><span class="w"> </span><span class="n">unlist</span><span class="p">(</span><span class="n">now_dates</span><span class="p">))</span><span class="w">
      
      </span><span class="c1"># who committed</span><span class="w">
      </span><span class="n">now_authors</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">lapply</span><span class="p">(</span><span class="n">commit_info</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">"author"</span><span class="p">)</span><span class="w">
      </span><span class="n">now_authors</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">lapply</span><span class="p">(</span><span class="n">now_authors</span><span class="p">,</span><span class="w"> </span><span class="s2">"[["</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">)</span><span class="w">
      </span><span class="n">authors</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="n">authors</span><span class="p">,</span><span class="w"> </span><span class="n">unlist</span><span class="p">(</span><span class="n">now_authors</span><span class="p">))</span><span class="w">
      
      </span><span class="n">page</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">page</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
  
  </span><span class="n">results</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">tibble</span><span class="o">::</span><span class="n">tibble</span><span class="p">(</span><span class="n">commit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">messages</span><span class="p">,</span><span class="w">
                           </span><span class="n">repo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">repo</span><span class="p">,</span><span class="w">
                           </span><span class="n">owner</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">who</span><span class="p">,</span><span class="w">
                           </span><span class="n">author</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">,</span><span class="w">
                           </span><span class="n">datetime</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dates</span><span class="p">)</span><span class="w">
  </span><span class="c1"># I only want commits from Lucy herself</span><span class="w">
  </span><span class="n">dplyr</span><span class="o">::</span><span class="n">filter_</span><span class="p">(</span><span class="n">results</span><span class="p">,</span><span class="w"> 
                 </span><span class="n">lazyeval</span><span class="o">::</span><span class="n">interp</span><span class="p">(</span><span class="o">~</span><span class="w"> </span><span class="n">stringr</span><span class="o">::</span><span class="n">str_detect</span><span class="p">(</span><span class="n">author</span><span class="p">,</span><span class="w"> </span><span class="s2">"[Ll]ucy"</span><span class="p">)))</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">commits</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">purrr</span><span class="o">::</span><span class="n">map2</span><span class="p">(</span><span class="n">lucy_repos</span><span class="o">$</span><span class="n">repos</span><span class="p">,</span><span class="w">
                       </span><span class="n">lucy_repos</span><span class="o">$</span><span class="n">who</span><span class="p">,</span><span class="w"> 
                       </span><span class="n">get_all_lucy_commits</span><span class="p">)</span><span class="w">
</span><span class="n">commits</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">dplyr</span><span class="o">::</span><span class="n">bind_rows</span><span class="p">(</span><span class="n">commits</span><span class="p">)</span><span class="w">
</span><span class="n">commits</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">dplyr</span><span class="o">::</span><span class="n">mutate</span><span class="p">(</span><span class="n">commits</span><span class="p">,</span><span class="w"> 
                         </span><span class="n">encoding</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">(</span><span class="n">commit</span><span class="p">))</span><span class="w">

</span><span class="n">commits</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">dplyr</span><span class="o">::</span><span class="n">mutate</span><span class="p">(</span><span class="n">commits</span><span class="p">,</span><span class="w"> 
                         </span><span class="n">datetime</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lubridate</span><span class="o">::</span><span class="n">ymd_hms</span><span class="p">(</span><span class="n">datetime</span><span class="p">))</span><span class="w">


</span><span class="n">head</span><span class="p">(</span><span class="n">commits</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">knitr</span><span class="o">::</span><span class="n">kable</span><span class="p">()</span><span class="w">
</span>
commit repo owner author datetime encoding
Rename park_dat_json.JSON to park_dat_json.json 2017-03-18_hackathon LucyMcGowan Lucy D’Agostino McGowan 2017-03-18 19:59:44 unknown
update json 2017-03-18_hackathon LucyMcGowan Lucy 2017-03-18 19:59:00 unknown
update json 2017-03-18_hackathon LucyMcGowan Lucy 2017-03-18 19:57:29 unknown
update json 2017-03-18_hackathon LucyMcGowan Lucy 2017-03-18 19:57:16 unknown
fix json 2017-03-18_hackathon LucyMcGowan Lucy 2017-03-18 19:31:56 unknown
first commit 2017-03-18_hackathon LucyMcGowan Lucy 2017-03-18 19:23:06 UTF-8

Looking at emojis

I used this awesome emoji dictionary created and presented in this blog.

<span class="n">dico</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">readr</span><span class="o">::</span><span class="n">read_csv2</span><span class="p">(</span><span class="s2">"https://raw.githubusercontent.com/today-is-a-good-day/emojis/master/emDict.csv"</span><span class="p">)</span><span class="w">
</span><span class="n">head</span><span class="p">(</span><span class="n">dico</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">knitr</span><span class="o">::</span><span class="n">kable</span><span class="p">()</span><span class="w">
</span>
Description Native Bytes R-encoding
AERIAL TRAMWAY \xF0\x9F\x9A\xA1
AIRPLANE \xE2\x9C\x88 <9c><88>
ALARM CLOCK \xE2\x8F\xB0 <8f>
ALIEN MONSTER \xF0\x9F\x91\xBE
AMBULANCE \xF0\x9F\x9A\x91 <91>
AMERICAN FOOTBALL \xF0\x9F\x8F\x88 <88>

As the Github username of the person who created, today is a good day! Like in my last post I’ll use fuzzyjoin to identify emojis.

<span class="n">library</span><span class="p">(</span><span class="s2">"fuzzyjoin"</span><span class="p">)</span><span class="w">

</span><span class="n">commits_decoded</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">regex_inner_join</span><span class="p">(</span><span class="n">commits</span><span class="p">,</span><span class="w"> </span><span class="n">dico</span><span class="p">,</span><span class="w">
                            </span><span class="n">by</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="n">commit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Native"</span><span class="p">))</span><span class="w">
</span>

Yes! Doing this, I got 63 emojis!

<span class="n">table</span><span class="p">(</span><span class="n">commits_decoded</span><span class="o">$</span><span class="n">Description</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">broom</span><span class="o">::</span><span class="n">tidy</span><span class="p">()</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">dplyr</span><span class="o">::</span><span class="n">arrange</span><span class="p">(</span><span class="n">desc</span><span class="p">(</span><span class="n">Freq</span><span class="p">))</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">head</span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">10</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">knitr</span><span class="o">::</span><span class="n">kable</span><span class="p">()</span><span class="w">
</span>
Var1 Freq
SEE-NO-EVIL MONKEY 10
ROOSTER 8
BUG 4
FACE WITH OK GESTURE 4
NAIL POLISH 3
PARTY POPPER 3
FACE SCREAMING IN FEAR 2
INFORMATION DESK PERSON 2
RUNNER 2
SUNFLOWER 2

Seeing the frequency of the “see no evil” emoji… Is Lucy ashamed of her commits? Why, Lucy? Then, rooster is a chicken, and Lucy is trying to make the “#RChickenLadies” hashtag happen (note to self: Lucy probably has puns in her commit messages). One important point though, on top of these cool most frequent emojis, is the diversity of emojis, 33 unique emojis for 63 emojis in total. It’s a real language! I can’t wait for Lucy to commit and push more in her public repositories to try and decode this language! And also to see the awesome work behind each commit, of course.

To leave a comment for the author, please follow the link and comment on their blog: Maëlle.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)