If you’re like me, you use a lot of loops in R. I do not profess to be the most efficient coder, but loops make sense to me and I’m generally not concerned about make the fastest simulations.
But sometimes my loops take some time to finish, so I often add a rolling text update during the simulation to know how far it has progressed. But of course, I have to look at the R console to see how far things have come. Being a bit away from the central tendency of the spectrum, I can get absorbed in doing other things, so I often miss when the simulation is complete.

In a fit of excess geekiness, I’ve recently discovered voice prompts in MacOS that I can now code directly into my R simulations to give verbal updates on their progress. I find these immensely useful. I’ve therefore decided to share the basic code, because I know some other geeks out there might also appreciate the tool. Apologies — I haven’t investigated how to do this in a PC environment, so the following examples are MacOS-specific.
First, go to your Accessibility settings in System Settings in your Mac. Click on System Voice to see what voices you have access to, and which voices you wish to download to your machine. There are many languages supported.
When you construct a loop in R, add the following code within and before the loop content (this example is in English):
iter <- 1000 # number of iterations
itdiv <- iter/100 # iteration divisor 1
itdiv2 <- iter/10 # iteration divisor 2
st.time <- Sys.time() # time at start of simulation
# loop from 1 to iter
for (i in 1:iter) {
# pause execution for 0.05 seconds (this would normally be the guts of your loop functions)
Sys.sleep(0.05)
# loop updaters with voice (English)
if (i %% itdiv==0) print(paste("iter = ", i, sep=""))
if (i %% itdiv2==0 & i < iter) system2("say", c("-v", "Fiona", paste(round(100*(i/iter), 0),
"per cent complete"))) # updates every 10% complete
if (i == 0.95*iter) system2("say", c("-v", "Fiona", paste(round(100*(i/iter), 0),
"per cent complete"))) # announce at 95% complete
if (i == 0.99*iter) system2("say", c("-v", "Fiona", paste(round(100*(i/iter), 0),
"per cent complete"))) # announce at 99% complete
if (i == iter) system2("say", c("-v", "Lee", "simulation complete"))
if (i == iter) system2("say", c("-v", "Lee", paste(round(as.numeric(Sys.time() - st.time,
units = "mins"), 2), "minutes elapsed")))
}
Here I’ve used the female Scottish voice ‘Fiona’ and the male Australian voice ‘Lee’.
Here’s an example in French:
iter <- 1000 # nombre d'iterations
itdiv <- iter/100 # diviseur 1
itdiv2 <- iter/10 # diviseur 2
st.time <- Sys.time() # heure du commencement de la simulation
# boucle
for (i in 1:iter) {
# pauser l'éxécution pendant 0,05 secondes (emplacement typique des fonctions dans la boucle)
Sys.sleep(0.05)
# mise à jour avec les voix
if (i %% itdiv==0) print(paste("iter = ", i, sep=""))
if (i %% itdiv2==0 & i < iter) system2("say", c("-v", "Aurélie", paste(round(100*(i/iter), 0),
"% terminé")))
if (i == 0.95*iter) system2("say", c("-v", "Aurélie", paste(round(100*(i/iter), 0), "% terminé")))
if (i == 0.99*iter) system2("say", c("-v", "Aurélie", paste(round(100*(i/iter), 0), "% terminé")))
if (i == iter) system2("say", c("-v", "Aurélie", "simulation terminée"))
if (i == iter) system2("say", c("-v", "Aurélie", paste(round(as.numeric(Sys.time() - st.time,
units = "mins"), 2), "minutes se sont écoulées")))
}
And an example in Italian:
iter <- 1000 # numero di iterazioni
itdiv <- iter/100 # divisore 1
itdiv2 <- iter/10 # divisore 2
st.time <- Sys.time() # tempo all'inizio della simulazione
# ciclo
for (i in 1:iter) {
# mettere in pausa l'esecuzione per 0,05 secondi (inserisci qui le tue funzioni di simulazione tipiche)
Sys.sleep(0.05)
# aggiornamenti vocali
if (i %% itdiv==0) print(paste("iter = ", i, sep=""))
if (i %% itdiv2==0 & i < iter) system2("say", c("-v", "Alice", paste("completato al",
round(100*(i/iter), 0), "%")))
#if (i == 0.95*iter) system2("say", c("-v", "Alice", paste("completato al", round(100*(i/iter), 0),
"%")))
#if (i == 0.99*iter) system2("say", c("-v", "Alice", paste("completato al", round(100*(i/iter), 0),
"%")))
if (i == iter) system2("say", c("-v", "Alice", "simulazione completa"))
#if (i == iter) system2("say", c("-v", "Alice", paste("sono passati", round(as.numeric(Sys.time()
- st.time, units = "mins"), 2), "minuti")))
}
There you have it. Enjoy geeking out!