One weird trick to {monetize} your R package

monetize
r
Author
Published

August 1, 2023

Three green dollar symbols in Comic Sans, each with an emoji hat on.

tl;dr

The {monetize} R package gives you inspiration for monetising your R package. Developers rise up!

Free as in free

There’s one good reason why SAS, SPSS and Stata1 are such successful and beloved statistical tools: money.

For some reason, R remains free and open source. But what if Ihaka & Gentleman originally wanted users to be charged a literal (New Zealand) dollar2 every time they use the $ symbol to access an element from an object? I’m just asking the question!

Us package developers should seize the initiative and harvest the sweet, sweet bounty of our labour. But how? I will tell you the secret!

Free as in not quite

Introducing the {monetize} R package! It will provide the inspiration you seek. Serious entrepreneurs can install from GitHub3.

install.packages("remotes")  # if not yet installed
remotes::install_github("matt-dray/monetize")
library(monetize)
Welcome to the monetize(TM) package FREE TRIAL version!
Try our EXCLUSIVE add_one() function!
Try watch_ad() to gain MEGA COINS and increase your MEMBER LEVEL for REWARDS!
And now a quick message from our sponsor:
  🧃 IMBIBE ACME(TM)-BRAND FRUIT PULP (7% FEWER INSECT COMPONENTS)! 🪳

The package contains the exclusive add_one() function, which surprisingly doesn’t come pre-installed with base R. A gap in the market!

Users should speculate to accumulate, so there’s a small cost to use the function. In {monetize}, each use of a function costs 1 MEGA COIN.

Because I am so kind, I have chosen for users to receive a 30-day FREE TRIAL of the package and to receive 3 MEGA COINS as an exclusive NEW-MEMBER PERK.

One use of the function costs the low, low price of 1 MEGA COIN. Merely a small payment, or ‘micro transaction’, if you will.

add_one(1)
📅 You have 30 days left of your FREE TRIAL!
🏅 Your MEMBER LEVEL is 1! Try watch_ad()!
💰 Your MEGA COIN balance is now 2! Try watch_ad()!
[1] 2

Along with the result, the function helpfully prints the number of days left in your FREE TRIAL, your MEMBER LEVEL and the number of MEGA COINS you have left.

What’s a MEMBER LEVEL? Well, at MEMBER LEVEL 1, the function can’t guarantee a correct result. 20% of the time there’ll be an off-by-one error. But R users index from 1 anyway, so they’ll be used to that.

add_one(1)
📅 You have 30 days left of your FREE TRIAL!
🏅 Your MEMBER LEVEL is 1! Try watch_ad()!
💰 Your MEGA COIN balance is now 1! Try watch_ad()!
[1] 3

How can you get the correct result 100% of the time? That’s an exclusive for MEMBER LEVEL 2. How do you reach MEMBER LEVEL 2? What happens if you run out of MEGA COINS?

add_one(1)
📅 You have 30 days left of your FREE TRIAL!
🏅 Your MEMBER LEVEL is 1! Try watch_ad()!
Error: 😭 You'll need more MEGA COINS to re-use this function! Try watch_ad()!

Answer: simply watch some ads! I’ve managed to get an ad deal with the famous Acme(TM) Corporation. Maybe you could get a sponsorship deal from a third-party whose interests align with your users’ interests; maybe SAS, SPSS or Stata would be interested?

Anyway, the user can just watch_ad() in exchange for MEGA COINS: I’ve allowed the user to employ their FREE WILL to watch a "short" ad for 1 MEGA COIN or a "long" ad for 3 MEGA COINS.

watch_ad("short")
🌭 CONSUME ACME(TM)-BRAND RECONSTITUTED MEAT-LIKE CYLINDERS! 🐕
🌭 CONSUME ACME(TM)-BRAND RECONSTITUTED MEAT-LIKE CYLINDERS! 🐕
🌭 CONSUME ACME(TM)-BRAND RECONSTITUTED MEAT-LIKE CYLINDERS! 🐕
🌭 CONSUME ACME(TM)-BRAND RECONSTITUTED MEAT-LIKE CYLINDERS! 🐕
🌭 CONSUME ACME(TM)-BRAND RECONSTITUTED MEAT-LIKE CYLINDERS! 🐕
Congratulations! Your new MEGA COIN total is 1!

Reach MEMBER LEVEL 2 after gaining 10 all-time MEGA COINS and MEMBER LEVEL 3 after 20 MEGA COINS.

What’s the exclusive MEMBER LEVEL 3? Well, you get the perk of an actually-correct answer like in MEMBER LEVEL 2… plus the value gets a randomised FREE HAT!

add_one(1)
📅 You have 30 days left of your FREE TRIAL!
🏅 Your MEMBER LEVEL is 3! Try watch_ad()!
💰 Your MEGA COIN balance is now 19! Try watch_ad()!
🎩 
 2 

What a tease! Oh, and the stats are persistent, so your users can’t refresh their session and wipe the slate clean. Watch the cash roll in!

Free as in absolutely not

I hope this has been an inspirational eye-opener for you and that one day you can be as rich as me. Oh, you didn’t know I was rich? How else could I afford to keep this absolute juggernaut of a blog going?

To demonstrate how little I personally need them, here are some more ideas to maximise your financial rewards via R. You could try:

  • releasing version updates as paid add-ons, like videogame DLC (you could also make them take several hours to download, like videogame DLC, which would definitely heighten the tension)
  • loot boxes to allow users to gamble—I mean, test their precognitive skills—for new functionality (add_two() could be a common drop, while multiply_by_two() is ultra rare)
  • using certified financial guru Duncan Garmonsway’s {ggbillboard} package (‘use vacant ggplot2 facets for advertising’)

You are welcome. Don’t read the small print for nerds.

Small print for nerds. It’s a simple trick: up-to-date stats are stored on the user’s computer in the directory resolved by tools::R_user_dir("monetize", "data")4 and are updated each time you use the functions in the package. Easy to circumvent… if you know how.

Environment

Session info
Last rendered: 2023-08-01 11:37:35 BST
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] monetize_0.0.0.9000

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.2 compiler_4.3.1    fastmap_1.1.1     cli_3.6.1        
 [5] tools_4.3.1       htmltools_0.5.5   rstudioapi_0.15.0 yaml_2.3.7       
 [9] rmarkdown_2.23    knitr_1.43.1      jsonlite_1.8.7    xfun_0.39        
[13] digest_0.6.33     rlang_1.1.1       evaluate_0.21    

Footnotes

  1. Curious why they all start with ‘S’? It’s in deference to ‘R’, which comes first in the alphabet and in being really cool.↩︎

  2. Did you also know that the use of the New Zealand dollar is part of a wider conspiracy? The sheep dip goes deep on this one.↩︎

  3. Don’t.↩︎

  4. I consider this my hattrick of posts on R_user_dir(). I wrote about it as a way to cache data from the PokéAPI in {trapinch} and store cyber pet blueprints in {tamRgo}, the latter of which led to a post on saving high-score data with {hiscore}.↩︎

Reuse

CC BY-NC-SA 4.0