Animal Crossing Tinder with {shinysense}


June 6, 2020

Screenshot of the ACNH Popularity Contest app showing a villager that the user is being asked to swipe left to dislike or right to like.

Lily <3 4eva


The villagers of Animal Crossing: New Horizons are taking part in a popularity contest and you’re the judge.

I made an R Shiny app where you swipe right if you like a randomly-presented villager and left if you dislike them.

Visit the app here and help decide the most popular villager! You can also visit the source code.

Tidy Tuesday

Tidy Tuesday is an open event for the R community. The organisers provide a data set and participants submit their take on wrangling and presenting the data, usually via Twitter with the hashtag #tidytuesday.

A recent data set (week 19) via VillagerDB includes information about villager non-player characters from the wildly popular Animal Crossing: New Horizons game for the Nintendo Switch. A similar set of data was also uploaded to Kaggle.

I couldn’t resist, having recently written about learning R6 object-oriented programming with an Animal Crossing example.

This was also a good chance to learn more about two packages in particular: {shinysense} and {googlesheets4}.


Nick Strayer‘s {shinysense} package lets Shiny ’sense the world around it’, with modules for touch, vision, hearing and motion.

I wanted to try out shinyswipr, which presents a user with a ‘card’ that they can swipe. The direction of swiping can be used to indicate something, like a preference. After swiping, the card content can be updated.

You can read Nick’s blog post about its inception.


In Nick’s shinyswipr example, he presents back to the user their swipe history, but how can we record the information from all users and return the collated results?

There’s a number of ways to do persistent storing with Shiny, but a relatively simple one is to write the data to Google Sheets and read the entire sheet back into the app.

The {googlesheets4} package by Jenny Bryan helps you do exactly that, with functions like sheet_append() and read_sheet().

The ACNH Popularity Contest

There’s a lot of articles online about favourite villagers, but they aren’t very democratic. They tend to cite characters like Raymond, Beau, Marshal, Judy and Audie.

It’s time to let the people speak.

How to use

If you visit the app, or look at the image at the top of this post, you’ll see that the user is presented with a card containing a randomly-selected villager and some details (name, species, personality and hobby).

You can move the card to the right to indicate you like the character, or to the left if you dislike them. On mobile you can swipe left or right with your finger. On desktop you can click and drag the card.

Gif showing a blue card on a green background. The card has a picture of a villager from Nintendo's Animal Crossing game with their name, personality type, species and hobby. A mouse cursor swipes the card to the right, meaning 'like', and another card appears with a different character. The card is swiped to the left, meaning 'dislike'.

No dates guaranteed. The characters aren’t actually real, y’see.

The swipe event results in the information being written to a Google Sheet and triggers the entirety of the updated data set to be read back to the app. It’s then wrangled lightly and the information is presented as a table of the current top 10 villagers by ‘like’ count. Finally, a new random villager is presented.

This is obviously a bit of fun and definitely not polished. Do let me know of any bugs that you find, though. I’m aware that mobiles may not display the fonts correctly, for example.

Data and hosting

No data about the user is stored. The app records only the date-time, the villager name and the swipe direction.

The app is hosted for free on, so there’s a limited number of uptime hours it can use per month.


I hope that enough people cast a vote to make the results interesting… but there’s nearly 400 villagers, so that seems unlikely!


I’ve written a more recent post where I aggregated the results for the thousands of swipes that people made in the app!


Session info
Last rendered: 2023-07-19 21:47:26 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

[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     

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       fontawesome_0.5.1 evaluate_0.21