RObservations #26-Turning Raffle Ticket Purchases info into Raffle Entries with Base R

[This article was first published on r – bensstats, 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.

Introduction

Recently, a friend running a non-profit reached out to me for some help with transforming his data. He ran a raffle campaign where he sold tickets to donors and wanted to turn the record of ticket sales into a record of raffle entries. The problem usually would take the secretaries in the office a few hours, but with a little bit of R code- its possible to get it done in a instant. In this blog I am going to share how its possible to turn raffle ticket purchase records into raffle ticket entries by using the replicate(), apply() and do.call() functions.

The Data

Since the data that I was given was private information, I can’t share the real data here. For demonstration purposes I created some fake data using random-name-generator.com and some random numbers. The records of ticket purchases which I made up is:

raffleData <- data.frame("Name" = c("Elliot Morin",
                                    "Caleb Murphy",
                                    "Zoe Clark",
                                    "Mason  Li",
                                    "Nathan Levesque",
                                    "Colton Gagne"),
                         "Tickets_Bought" = c(5,10,9,12,3,6))

raffleData


##              Name Tickets_Bought
## 1    Elliot Morin              5
## 2    Caleb Murphy             10
## 3       Zoe Clark              9
## 4       Mason  Li             12
## 5 Nathan Levesque              3
## 6    Colton Gagne              6

To turn these records into entries, we want a data set with Elliot Morin having 5 instances of his name, Caleb Murphy having 10 instances, Zoe Clark 9 etc. To do this we are going to need to use four base R functions- replicate(), apply(), do.call() and rbind().

Now, lets walk through explaining how the functions work.

Using replicate()

replicate() is a function that will allow you replicate a object while preserving structure. So if we want to replicate the vector c(1,2,3) three times, we will get a 3 x 3 matrix with each column being c(1,2,3).

replicate(3,c(1,2,3))


##      [,1] [,2] [,3]
## [1,]    1    1    1
## [2,]    2    2    2
## [3,]    3    3    3

This is great because if we want to replicate Elliot Morin 5 times, we can do it with his purchase record by using replicate and transposing. To avoid using tidyverse, you can use the base R pipe operator or nest the function. Because I like the pipe operator, I’ll write my codes with it.

replicate(5,c("Elliot Morin",5)) |>  t()


##      [,1]           [,2]
## [1,] "Elliot Morin" "5" 
## [2,] "Elliot Morin" "5" 
## [3,] "Elliot Morin" "5" 
## [4,] "Elliot Morin" "5" 
## [5,] "Elliot Morin" "5"

Using apply()

Now that we’ve used replicate, we can use the apply() function to iterate by row by setting MARGIN=1 to create the repeated entries. The code to do this in base R is:

raffleData |> apply(1, function(x) replicate(x[2],x) |> t())


## [[1]]
##      Name           Tickets_Bought
## [1,] "Elliot Morin" " 5"          
## [2,] "Elliot Morin" " 5"          
## [3,] "Elliot Morin" " 5"          
## [4,] "Elliot Morin" " 5"          
## [5,] "Elliot Morin" " 5"          
## 
## [[2]]
##       Name           Tickets_Bought
##  [1,] "Caleb Murphy" "10"          
##  [2,] "Caleb Murphy" "10"          
##  [3,] "Caleb Murphy" "10"          
##  [4,] "Caleb Murphy" "10"          
##  [5,] "Caleb Murphy" "10"          
##  [6,] "Caleb Murphy" "10"          
##  [7,] "Caleb Murphy" "10"          
##  [8,] "Caleb Murphy" "10"          
##  [9,] "Caleb Murphy" "10"          
## [10,] "Caleb Murphy" "10"          
## 
## [[3]]
##       Name        Tickets_Bought
##  [1,] "Zoe Clark" " 9"          
##  [2,] "Zoe Clark" " 9"          
##  [3,] "Zoe Clark" " 9"          
##  [4,] "Zoe Clark" " 9"          
##  [5,] "Zoe Clark" " 9"          
##  [6,] "Zoe Clark" " 9"          
##  [7,] "Zoe Clark" " 9"          
##  [8,] "Zoe Clark" " 9"          
##  [9,] "Zoe Clark" " 9"          
## 
## [[4]]
##       Name        Tickets_Bought
##  [1,] "Mason  Li" "12"          
##  [2,] "Mason  Li" "12"          
##  [3,] "Mason  Li" "12"          
##  [4,] "Mason  Li" "12"          
##  [5,] "Mason  Li" "12"          
##  [6,] "Mason  Li" "12"          
##  [7,] "Mason  Li" "12"          
##  [8,] "Mason  Li" "12"          
##  [9,] "Mason  Li" "12"          
## [10,] "Mason  Li" "12"          
## [11,] "Mason  Li" "12"          
## [12,] "Mason  Li" "12"          
## 
## [[5]]
##      Name              Tickets_Bought
## [1,] "Nathan Levesque" " 3"          
## [2,] "Nathan Levesque" " 3"          
## [3,] "Nathan Levesque" " 3"          
## 
## [[6]]
##      Name           Tickets_Bought
## [1,] "Colton Gagne" " 6"          
## [2,] "Colton Gagne" " 6"          
## [3,] "Colton Gagne" " 6"          
## [4,] "Colton Gagne" " 6"          
## [5,] "Colton Gagne" " 6"          
## [6,] "Colton Gagne" " 6"

With this code, we managed to get our repeated entries for the raffle, but the data is in list form. We are going to need to now combine the data together into a single data frame. This can be accomplished with do.call() and rbind()

Using do.call() and rbind()

do.call() allows us to execute a function call on the entire list. By calling rbind, the list of matrices is combined into a single matrix. For personal preference I’ll coerce it to a data frame and have the Tickets_Bought column be numeric by using the within() function. but it should work if exported as a matrix.

Since do.call() is constructed with the function call as the first argument, using the pipe operator will not be helpful and will have to be nested.

The code is:

do.call(rbind,
        raffleData |> apply(1, function(x) replicate(x[2],x) |> t())
        ) |> 
        # Optional- coerce to data frame and coerce Tickets_Bought to numeric
        as.data.frame() |>
        within({
          Tickets_Bought<- as.numeric(Tickets_Bought)
        })


##               Name Tickets_Bought
## 1     Elliot Morin              5
## 2     Elliot Morin              5
## 3     Elliot Morin              5
## 4     Elliot Morin              5
## 5     Elliot Morin              5
## 6     Caleb Murphy             10
## 7     Caleb Murphy             10
## 8     Caleb Murphy             10
## 9     Caleb Murphy             10
## 10    Caleb Murphy             10
## 11    Caleb Murphy             10
## 12    Caleb Murphy             10
## 13    Caleb Murphy             10
## 14    Caleb Murphy             10
## 15    Caleb Murphy             10
## 16       Zoe Clark              9
## 17       Zoe Clark              9
## 18       Zoe Clark              9
## 19       Zoe Clark              9
## 20       Zoe Clark              9
## 21       Zoe Clark              9
## 22       Zoe Clark              9
## 23       Zoe Clark              9
## 24       Zoe Clark              9
## 25       Mason  Li             12
## 26       Mason  Li             12
## 27       Mason  Li             12
## 28       Mason  Li             12
## 29       Mason  Li             12
## 30       Mason  Li             12
## 31       Mason  Li             12
## 32       Mason  Li             12
## 33       Mason  Li             12
## 34       Mason  Li             12
## 35       Mason  Li             12
## 36       Mason  Li             12
## 37 Nathan Levesque              3
## 38 Nathan Levesque              3
## 39 Nathan Levesque              3
## 40    Colton Gagne              6
## 41    Colton Gagne              6
## 42    Colton Gagne              6
## 43    Colton Gagne              6
## 44    Colton Gagne              6
## 45    Colton Gagne              6

With the above code, the raffle ticket purchases have been converted to raffle ticket entries. Pretty cool, don’t you think?

I have been recently trying my hand at doing this with SQLite and I must say that its much more complicated involving CTE statements and Recursion. But if you’re using R, this is a pretty straight forward solution.

Thanks for reading! Be sure to subscribe and share with your friends!

Want to see more of my content?

Be sure to subscribe and never miss an update!

To leave a comment for the author, please follow the link and comment on their blog: r – bensstats.

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)