Amy Whitehead's Research

the ecological musings of a conservation biologist

Santa’s Little Helper – a function for randomly assigning Secret Santa presents

3 Comments

Christmas can be a stressful and expensive time of year, with many gifts to buy for many people. My family have tried to eliminate some of this stress by having a Secret Santa gifting system where we all buy one present for one member of the family on behalf of everybody else, with a cap of $50 per present.

In our family scheme, there are 3 rules:
1. You can’t give a gift to yourself,
2. You can’t give a gift to your partner (we figure that this will happen anyway),
3. You can’t give a gift to someone you gave one to last year.

Somewhere along the line, I’ve become the designated present-assigner. Now I could write names on pieces of paper and put them in a hat but 1) writing out 11 names is tedious, 2) I don’t have a suitable hat and 3) the rules above mean that there are quite often gifting conflicts arise that require the need for a redraw. So I’ve whipped up a little function in R that does the job. (Admittedly it probably would have been faster to use bits of paper but now I’m prepared for next year).

SantasLittleHelper <- function(myFrame,guestList,conflictCols = NULL){
  myTest <- TRUE
  nElves <- 0

  while (myTest == TRUE){
    myOut <- data.frame(gifter = myFrame[,guestList],
                        giftee = sample(myFrame[,guestList],
                                        replace = FALSE,
                                        size=nrow(myFrame))
                        )

    # check that guests haven't drawn themselves
    guestTest<- unlist(lapply(1:nrow(myOut),function(x) {
      myOut$giftee[x] == myFrame[x,guestList]
      }))

    # check for gifting conflicts
    if(!is.null(conflictCols)){

    conflictTest <- unlist(lapply(1:nrow(myOut),function(x) {
      grepl(myOut$giftee[x],myFrame[x,conflictCols])
      }))

    myTest <- any(c(guestTest,conflictTest[!is.na(conflictTest)]))

    } else{
      myTest <- any(guestTest)
    }

    # count the number of iterations needed to avoid conflicts
    nElves <- nElves + 1
  }

  message(paste(nElves,"elves were needed to generate the gift list"))
  return(myOut)
}

SantasLittleHelper takes three arguments: myFrame is a dataframe containing the list of guests to be assigned gifts; GuestList is the character name of the column containing the list of guests; and conflictCols is an optional character vector of column names that identify gifting conflicts that need to be avoided [1]. The function randomly assigns a giftee to each guest and then checks for conflicts. If conflicts exist, the gifts are reassigned and this continues using a while loop until a suitable solution is found. The function returns a dataframe containing detailing the gifter – giftee combinations, as well as outputting the number of elves (or iterations) needed to generate the list.

To run this for the 2016 Whitehead Family Christmas, I generated a dataframe guests where the column guest lists all of the people coming to Christmas, partner identifies everybody’s significant others and presents2013 lists the assigned giftees from 2013 (the last time we did the Secret Santa thing).

guest partner presents2013
John Fay Jo
Sue Simon Fay
Amy Hamish Sue
Jo Phil Hamish
Ashley Naomi Phil
Naomi Ashley John
Phil Jo Simon
Hamish Amy Naomi
Simon Sue Ashley
Fay John Amy
Zac NA NA

These data are fed into SantasLittleHelper and, bingo, the Whitehead Family Christmas is sorted for another year.

giftList <- SantasLittleHelper(myFrame = guests,
                               guestList = "guest",
                               conflictCols  = c("partner","presents2013")
                               )
27 elves were needed to generate the gift list
gifter giftee
John Zac
Sue Ashley
Amy Phil
Jo Amy
Ashley Fay
Naomi Sue
Phil John
Hamish Jo
Simon Naomi
Fay Simon
Zac Hamish

Hope everyone survives the silly season!

[Merry Christmas everyone!](http://www.r-bloggers.com/merry-christmas-5/)

[1] Technically you could use this feature to rig the outcome to avoid getting a present from Great Aunt Myrtle or Bob from Accounts by adding in an additional conflict column. Use your powers wisely or the ghosts of christmas past may come back to bite you!

Advertisements

3 thoughts on “Santa’s Little Helper – a function for randomly assigning Secret Santa presents

  1. Hi Amy,

    Have you seen Hannah Fry’s latest video on secret santa selection? I think some of her points pertain to your implementation; namely that by using purely random selection and redrawing when conflictions occur you actually bias certain paths down the probability tree as others can not be valid, this leads to the pairing being non-uniform (i.e. some pairs are more likely than others).

    Not trying to be critical, it’s a neat function, just thought you might be interested 🙂

    Happy holidays!

  2. This is great! Thanks for sharing!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s