library(reshape2)
library(ggplot2)
library(dplyr)
library(broom)
data <- read.csv("csv/all.csv")

Filtering and plotting

Then we define a function that can be used to filter the dataset to a particular encounter and difficulty. It also performs outlier filtering - for each 5-ilvl bucket, for each spec, we compute the 95th percentile of DPS, then remove any parses from the dataset for that ilvl/spec above that cutoff.

d <- data
m <- d %>% group_by(class, spec, encounter) %>% do(tidy(lm(dps ~ ilvl, data=.)))

slopes <- m[m$term == "ilvl",]

d <- data
m <- d %>% group_by(class, spec) %>% do(tidy(lm(dps ~ ilvl, data=.)))
all_slopes <- m[m$term == "ilvl",]
scale_encounter <- function(s, title) {
  s$class = with(s, factor(class, levels = rev(levels(class))))
  s$spec = with(s, factor(spec, levels = rev(levels(spec))))
  ggplot(data=s, aes(x=paste(class, spec), y=estimate, group=interaction(class, spec), reorder=estimate, fill=paste(class, spec))) +
    geom_bar(position=position_dodge(width = 0.9), stat="identity", colour="black") +
    labs(y="DPS gain/ilvl", x="Encounter", title=paste("DPS scaling per ilvl:", title)) +
    coord_flip() +
    guides(fill=FALSE)
}
scale_encounter(slopes[slopes$encounter == "Nythendra",], title="Nythendra")

scale_encounter(slopes[slopes$encounter == "Ursoc",], title="Ursoc")

scale_encounter(slopes[slopes$encounter == "Dragons_of_Nightmare",], title="Dragons_of_Nightmare")

scale_encounter(slopes[slopes$encounter == "Elerethe_Renferal",], title="Elerethe_Renferal")

scale_encounter(slopes[slopes$encounter == "Il_gynoth__Heart_of_Corruption",], title="Il_gynoth__Heart_of_Corruption")

scale_encounter(slopes[slopes$encounter == "Cenarius",], title="Cenarius")

scale_encounter(slopes[slopes$encounter == "Xavius",], title="Xavius")

scale_encounter(all_slopes, title="Overall")

LS0tDQp0aXRsZTogIkFsbCBzcGVjIHNjYWxpbmciDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIGZpZ19oZWlnaHQ6IDYNCiAgICBmaWdfd2lkdGg6IDE4DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCmBgYHtyfQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGJyb29tKQ0KZGF0YSA8LSByZWFkLmNzdigiY3N2L2FsbC5jc3YiKQ0KZGF0YSRkYXRlIDwtIGFzLkRhdGUoZGF0YSRkYXRlKQ0KY3V0b2ZmX2RhdGUgPSAiMjAxNi0xMC0xNSINCmBgYA0KDQojIyBGaWx0ZXJpbmcgYW5kIHBsb3R0aW5nDQoNClRoZW4gd2UgZGVmaW5lIGEgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBmaWx0ZXIgdGhlIGRhdGFzZXQgdG8gYSBwYXJ0aWN1bGFyIGVuY291bnRlciBhbmQgZGlmZmljdWx0eS4gSXQgYWxzbyBwZXJmb3JtcyBvdXRsaWVyIGZpbHRlcmluZyAtIGZvciBlYWNoIDUtaWx2bCBidWNrZXQsIGZvciBlYWNoIHNwZWMsIHdlIGNvbXB1dGUgdGhlIDk1dGggcGVyY2VudGlsZSBvZiBEUFMsIHRoZW4gcmVtb3ZlIGFueSBwYXJzZXMgZnJvbSB0aGUgZGF0YXNldCBmb3IgdGhhdCBpbHZsL3NwZWMgYWJvdmUgdGhhdCBjdXRvZmYuDQoNCmBgYHtyfQ0KZCA8LSBkYXRhDQptIDwtIGQgJT4lIGdyb3VwX2J5KGNsYXNzLCBzcGVjLCBlbmNvdW50ZXIpICU+JSBkbyh0aWR5KGxtKGRwcyB+IGlsdmwsIGRhdGE9LikpKQ0KDQpzbG9wZXMgPC0gbVttJHRlcm0gPT0gImlsdmwiLF0NCg0KZCA8LSBkYXRhDQptIDwtIGQgJT4lIGdyb3VwX2J5KGNsYXNzLCBzcGVjKSAlPiUgZG8odGlkeShsbShkcHMgfiBpbHZsLCBkYXRhPS4pKSkNCmFsbF9zbG9wZXMgPC0gbVttJHRlcm0gPT0gImlsdmwiLF0NCmBgYA0KDQpgYGB7ciwgZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD03fQ0Kc2NhbGVfZW5jb3VudGVyIDwtIGZ1bmN0aW9uKHMsIHRpdGxlKSB7DQogIHMkY2xhc3MgPSB3aXRoKHMsIGZhY3RvcihjbGFzcywgbGV2ZWxzID0gcmV2KGxldmVscyhjbGFzcykpKSkNCiAgcyRzcGVjID0gd2l0aChzLCBmYWN0b3Ioc3BlYywgbGV2ZWxzID0gcmV2KGxldmVscyhzcGVjKSkpKQ0KICBnZ3Bsb3QoZGF0YT1zLCBhZXMoeD1wYXN0ZShjbGFzcywgc3BlYyksIHk9ZXN0aW1hdGUsIGdyb3VwPWludGVyYWN0aW9uKGNsYXNzLCBzcGVjKSwgcmVvcmRlcj1lc3RpbWF0ZSwgZmlsbD1wYXN0ZShjbGFzcywgc3BlYykpKSArDQogICAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCBzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iYmxhY2siKSArDQogICAgbGFicyh5PSJEUFMgZ2Fpbi9pbHZsIiwgeD0iRW5jb3VudGVyIiwgdGl0bGU9cGFzdGUoIkRQUyBzY2FsaW5nIHBlciBpbHZsOiIsIHRpdGxlKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgZ3VpZGVzKGZpbGw9RkFMU0UpDQp9DQpzY2FsZV9lbmNvdW50ZXIoc2xvcGVzW3Nsb3BlcyRlbmNvdW50ZXIgPT0gIk55dGhlbmRyYSIsXSwgdGl0bGU9Ik55dGhlbmRyYSIpDQpzY2FsZV9lbmNvdW50ZXIoc2xvcGVzW3Nsb3BlcyRlbmNvdW50ZXIgPT0gIlVyc29jIixdLCB0aXRsZT0iVXJzb2MiKQ0Kc2NhbGVfZW5jb3VudGVyKHNsb3Blc1tzbG9wZXMkZW5jb3VudGVyID09ICJEcmFnb25zX29mX05pZ2h0bWFyZSIsXSwgdGl0bGU9IkRyYWdvbnNfb2ZfTmlnaHRtYXJlIikNCnNjYWxlX2VuY291bnRlcihzbG9wZXNbc2xvcGVzJGVuY291bnRlciA9PSAiRWxlcmV0aGVfUmVuZmVyYWwiLF0sIHRpdGxlPSJFbGVyZXRoZV9SZW5mZXJhbCIpDQpzY2FsZV9lbmNvdW50ZXIoc2xvcGVzW3Nsb3BlcyRlbmNvdW50ZXIgPT0gIklsX2d5bm90aF9fSGVhcnRfb2ZfQ29ycnVwdGlvbiIsXSwgdGl0bGU9IklsX2d5bm90aF9fSGVhcnRfb2ZfQ29ycnVwdGlvbiIpDQpzY2FsZV9lbmNvdW50ZXIoc2xvcGVzW3Nsb3BlcyRlbmNvdW50ZXIgPT0gIkNlbmFyaXVzIixdLCB0aXRsZT0iQ2VuYXJpdXMiKQ0Kc2NhbGVfZW5jb3VudGVyKHNsb3Blc1tzbG9wZXMkZW5jb3VudGVyID09ICJYYXZpdXMiLF0sIHRpdGxlPSJYYXZpdXMiKQ0Kc2NhbGVfZW5jb3VudGVyKGFsbF9zbG9wZXMsIHRpdGxlPSJPdmVyYWxsIikNCmBgYA==