I'm trying to model and plot the rate of learning Dance Dance Revolution over the past year.

I have data of the format below, with the score received for a song on a specific date and difficulty level. Songs have been played many times over the year, at a variety of difficulty levels. I'd like to model the skill learned over the year.

Date Played Song Difficulty Level Game Version Score Letter Grade Num Perfects Num Greats Num Goods Num Almosts Num Boos Num O.K.s Max Combo
March 12, 2021 Girls Just Wanna Have Fun Expert DDR Supernova 8381742 A 153 52 4 0 7 23 69

Each song is unique per game version, and the scores across game versions are non standard (some are in the hundred thousand range and some in the thousand range). There are a total of 8 game versions, 5 difficulty levels, and ~100 songs.

A trivial solution would be to do a linear regression of the score over days, but this would not take into account differences by song, difficulty level, or game version.

Any ideas how to model the learning rate in a less trivial way?

  • $\begingroup$ Are you talking about just one person (player), or do you have a set of people? How many games are you talking about? $\endgroup$ Mar 14, 2021 at 2:11
  • $\begingroup$ 2 people! Where each person has played essentially all games. And order of 500 games. $\endgroup$ Mar 14, 2021 at 2:24
  • 1
    $\begingroup$ You mention that you have the data generated by two people that played these songs over time. When you say that you'd like to have an estimate of the learning rate do you mean: - learning rate of a specific player? Or learning rate of a generic player? - learning rate of a song? I mean, how easy or hard a song gets through time and times played? - learning rate of a game version? I mean, comparing with other games, one game can be easier or harder? $\endgroup$ Mar 16, 2021 at 15:16
  • 1
    $\begingroup$ Thanks for the questions! I'm hoping to learn the learning rate over time for each player, so I could make a plot of time on the x axis and "skill" on the y axis for each player. $\endgroup$ Mar 16, 2021 at 19:37
  • $\begingroup$ You will need to infer player skill from the scores obtained when playing songs. So the variables assessing the performance are score, num perfects, num greats, num goods, num almosts, num boos, num OKs and max combo ? And letter grade is a function of said variables? Do you have any song-wise variables ? $\endgroup$
    – GuillaumeL
    Mar 19, 2021 at 13:51

1 Answer 1


I suggest a simple generalized linear model to start.

$score = \beta_0 + \beta_1 days + \beta_2 song + \beta_3 difficulty + \beta_4 version$


  • day = days since start of training
  • song = a categorical encoding of the song
  • difficulty = a categorical encoding of the difficulty
  • version = a categorical encoding of the version

Since score is positive, and since the residuals might be long tailed to higher scores, I chose a lognormal error distribution. You will need to inspect the data to determine the right error distribution.

I didn't add player to the regression, but you could add a categorical for player also.

in R:


dates <- as.Date("2021-01-01") + 0:365
song <- c(LETTERS, letters)
difficulty <- paste0("level", 1:5)
version <- paste0("version", 1:8)

# simulate data, you would read your data in (read.csv or something like it)
N <- 300
dat <- data.frame(date = dates[sample(1:length(dates), size = N, replace = TRUE)],
                  song = factor(song[sample(1:length(song), size = N, replace = TRUE)]),
                  diff = factor(difficulty[sample(1:length(difficulty), size = N, replace = TRUE)]),
                  vers = factor(version[sample(1:length(version), size = N, replace = TRUE)]))
dat$dayssincestart <- as.numeric(dat$date - as.Date("2021-01-01"))
dat$score <- with(dat, dayssincestart * 10 + as.numeric(song) * 1 + as.numeric(diff) * 2 + as.numeric(vers) * 3 + rlnorm(N, 1, 1))
# ensure that each song, diff, and vers is done at least 2x
all(table(dat$song) >= 2)
all(table(dat$diff) >= 2)
all(table(dat$vers) >= 2)

glm1 <- glm(score ~ dayssincestart + song + diff + vers, data = dat, family = gaussian(link = "log"))
glm0 <- glm(score ~ 1, data = dat, family = gaussian(link = "log"))

# accounting for song, difficulty, and version, is there a score trend with time?
#   (1) look at the model to see it it is significant overall
anova(glm1, glm0, test = "LRT")
# Yes, P < 0.05, there is at least one significant relationship
#   (2) look at the coefficient on days_since_start to determine if you learning with time
# Yes, p < 0.05 and the estimate is positive (5.29E-3 increase in score per day after accounting for level, song, and version)

# plot data
ggplot(dat, aes(x = date, y = score, col = diff)) +
  geom_point() +
  labs(x = "Date", y = "Score", col = "Difficulty")

# plot diagnostics
plot(glm1, which = 1) # structure of the residuals indicates a problem which would require re-fitting
plot(glm1, which = 2)
plot(glm1, which = 3)
plot(glm1, which = 4)

  • $\begingroup$ Awesome answer! I might give it a try this weekend. May I use the random data you generated? Also, you could try and use github.com/tidyverse/reprex to render your code in such way that the images appear in the answer :) $\endgroup$ Mar 19, 2021 at 16:25
  • $\begingroup$ You can absolutely use the random data. You should be able to reproduce it because I set the seed. I didn't know about using reprex to paste in the images. I'll take a look. $\endgroup$
    – R Carnell
    Mar 19, 2021 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.