Skip to content

Instantly share code, notes, and snippets.

@JyuNyar
Last active November 3, 2016 11:58
Show Gist options
  • Save JyuNyar/2a9d1cc3ad15bd2f8358be690911f34e to your computer and use it in GitHub Desktop.
Save JyuNyar/2a9d1cc3ad15bd2f8358be690911f34e to your computer and use it in GitHub Desktop.
library(ggplot2)
library(plyr)
library(dplyr)
library(tidyr)
library(jsonlite)
#Dataframe with all the class, spec combinations to test:
iterate=data.frame(Class=c(1,1,2,2,3,3,3,4,4,4,5,6,7,8,8,8,9,9,10,10,10,11,11,12),Spec=c(2,3,1,2,1,2,3,1,2,3,3,3,3,1,3,4,1,2,1,2,3,1,2,1))
fights= data.frame(id=c(1853,1873,1876,1841,1854,1877,1864),EncounterName=c("Nythendra","Il'gynoth","Renferal","Ursoc","Dragons of Nightmare","Cenarius","Xavius"))
#Loop and API lookup variables
fightcounterMax = 7
fightcounter = 1
counter = 24
class.rep.count=1
class=1
spec=2
key="your_key_here"
encounter=1853
metric="dps"
difficulty=4 #4 = heroic, 5 = mythic
limit= 1000
reps = 1000
page=1
#This single call before the loops creates the data frames that I store all the data into
datalist=fromJSON(paste("https://www.warcraftlogs.com/v1/rankings/encounter/",encounter,"?api_key=",key,"&metric=",metric,"&difficulty=",difficulty,"&class=",class,"&spec=",spec,"&limit=",limit,"&page=",page,sep=""))
datalist=datalist$rankings%>%select(name,class,spec,total,duration,itemLevel,size,startTime,talents)%>%unnest()
names(datalist)[9]="talentName"
datalist$talentRow=seq(from=1,to=7,by=1)
datalist$encounter=encounter
merged=datalist
#Loop cycles through the 7 fights of Emerald Nightmare from the table [fights]
while(fightcounter <= fightcounterMax){
print(paste("*** Encounter: ",fights[fightcounter,1]," ","Name: ",fights[fightcounter,2], "***"))
encounter = fights[fightcounter,1]
#Loop cycles through the 22 class + spec combinations from the table [iterate]
while(class.rep.count <= counter){
class = iterate[class.rep.count,1]
spec = iterate[class.rep.count,2]
print(paste("*** Class: ",class," ","Spec: ",spec, "***"))
if(tryCatch({
datalist=fromJSON(paste("https://www.warcraftlogs.com/v1/rankings/encounter/",encounter,"?api_key=",key,"&metric=",metric,"&difficulty=",difficulty,"&class=",class,"&spec=",spec,"&limit=",limit,"&page=",page,sep=""))
datalist=datalist$rankings%>%select(name,class,spec,total,duration,itemLevel,size,startTime,talents)%>%unnest()
}, error=function(e){1})==1)
{
class.rep.count=class.rep.count+1
next
}
else{
names(datalist)[9]="talentName"
datalist$talentRow=seq(from=1,to=7,by=1)
datalist$encounter=encounter
}
while(page<=reps){ #this inner loop cycles through pages of rankeds results from warcraftlogs. Default value is 1000 [reps] pages of 300 [limit] results per spec. The large number is to ensure all levels are sampled.
if (tryCatch({
import=fromJSON(paste("https://www.warcraftlogs.com/v1/rankings/encounter/",encounter,"?api_key=",key,"&metric=",metric,"&difficulty=",difficulty,"&class=",class,"&spec=",spec,"&limit=",limit,"&page=",page,sep=""))
import=import$rankings%>%select(name,class,spec,total,duration,itemLevel,size,startTime,talents)%>%unnest()
}, error=function(e){1})==1)
{
break
}
else{
print(page)
names(import)[9]="talentName"
import$talentRow=seq(from=1,to=7,by=1)
import$encounter=encounter
datalist=rbind(datalist,import)
page=page+1
}
}
merged = rbind(merged,datalist)
page=1
class.rep.count=class.rep.count+1
}
page=1
class.rep.count=1
fightcounter=fightcounter+1
}
print("End")
library(ggplot2)
library(plyr)
library(dplyr)
library(tidyr)
library(gridExtra)
################################################################################################################################################
palette.base = c("#C41F3B", "#FF7D0A", "#ABD473", "#69CCF0", "#00FF96", "#F58CBA", "#FFFFFF", "#FFF569","#0070DE","#9482C9","#C79C6E","#A330C9")
palette2 = c("#C41F3B","#BC0020", "#FF7D0A","#FFBB80", "#ABD473","#72B910","#7EA647", "#69CCF0","#52A7C6", "#397E97", "#00FF96", "#F58CBA", "#000000","#D1C306","#C7BA13", "#0070DE","#609EDA", "#9482C9","#AEA2CF","#765DBB", "#C79C6E","#CDB69E")
palette2.full= c("#C41F3B","#BC0020", "#FF7D0A","#FFBB80", "#ABD473","#72B910","#7EA647", "#69CCF0","#52A7C6", "#397E97", "#00FF96", "#F58CBA", "#000000", "#C2B946","#D1C306","#C7BA13", "#0070DE","#609EDA", "#9482C9","#AEA2CF","#765DBB", "#C79C6E","#CDB69E","#A330C9")
palette3 = c("#C41F3B","#BC0020", "#FF7D0A","#FFBB80", "#ABD473","#72B910","#7EA647", "#69CCF0","#52A7C6", "#397E97", "#00FF96", "#F58CBA", "#FFFFFF","#D1C306","#C7BA13", "#0070DE","#609EDA", "#9482C9","#AEA2CF","#765DBB", "#C79C6E","#CDB69E")
classes = list(id=1:12,name=c("Death Knight","Druid","Hunter","Mage","Monk","Paladin","Priest","Rogue","Shaman","Warlock","Warrior","Demon Hunter"))
dk=list(id = 1:3, name = c("Blood", "Frost", "Unholy"))
druid=list(id = 1:4, name = c("Balance", "Feral", "Guardian", "Restoration"))
hunter=list(id = 1:3, name = c("Beast Mastery", "Marksmanship", "Survival"))
mage=list(id = 1:3, name = c("Arcane", "Fire", "Frost"))
monk=list(id = 1:3, name = c("Brewmaster", "Mistweaver", "Windwalker"))
paladin=list(id = 1:3, name = c("Holy", "Protection", "Retribution"))
priest=list(id = 1:3, name = c("Discipline", "Holy", "Shadow"))
rogue=list(id = 1:4, name = c("Assassination", "Combat", "Subtlety", "Outlaw"))
shaman=list(id = 1:3, name = c("Elemental", "Enhancement", "Restoration"))
warlock=list(id = 1:3, name = c("Affliction", "Demonology", "Destruction"))
warrior=list(id = 1:4, name = c("Arms", "Fury", "Protection", "Gladiator"))
demonh=list(id = 1:2, name = c("Havoc", "Vengeance"))
specs = list(id=c("1 2","1 3", "2 1", "2 2", "3 1", "3 2","3 3", "4 1", "4 2", "4 3", "5 3", "6 3", "7 3", "8 1", "8 3", "9 1", "9 2", "10 1", "10 2", "10 3", "11 1", "11 2"), name = c("Frost-Dk", "Unholy", "Balance", "Feral","Beast Mastery","Marksmanship","Survival","Arcane","Fire","Frost","Windwalker","Retribution","Shadow","Assassination","Subtlety","Elemental","Enhancement","Affliction","Demonology","Destruction","Arms","Fury"))
fightsnames = list(id=c(1853,1873,1876,1841,1854,1877,1864),EncounterName=c("Nythendra","Il'gynoth","Renferal","Ursoc","Dragons of Nightmare","Cenarius","Xavius"))
################################################################################################################################################
ursoc.dps = merged
names(ursoc.dps)[9]="talentName"
ursoc.dps=unique(ursoc.dps)
ursoc.dps=ursoc.dps%>%select(player=name,class,spec,total,duration,itemLevel,size,startTime,talentRow,talentName,encounter)
ursoc.dps=ursoc.dps%>%spread(talentRow,talentName)
ursoc.dps=ursoc.dps%>%mutate(spec2=paste(as.character(class),as.character(spec)))
ursoc.dps$class=factor(ursoc.dps$class,levels=classes$id,labels=classes$name)
ursoc.dps$Fight=factor(ursoc.dps$encounter,levels=fightsnames$id,labels=fightsnames$EncounterName)
ursoc.dps$spec2 = factor(ursoc.dps$spec2,levels=specs$id,labels=specs$name)
ursoc.dps$Date=as.Date(as.POSIXct(ursoc.dps$startTime/1000, origin="1970-01-01"))
ursoc.dps.filtered=ursoc.dps%>%filter(Date>"2016-10-24",spec2!="NA")
ursoc.dps.filtered=ursoc.dps.filtered%>%group_by(spec2)%>%mutate(fullMedian=median(total))%>%ungroup()%>%group_by(spec2,Fight)%>%mutate(lower = (median(total)-2.5*mad(total)),upper = (median(total)+2.5*mad(total)))
ursoc.dps.filtered$outlier=ifelse(ursoc.dps.filtered$total<ursoc.dps.filtered$lower,1,ifelse(ursoc.dps.filtered$total>ursoc.dps.filtered$upper,1,0))
ursoc.dps.filtered=ursoc.dps.filtered%>%filter(outlier==0)%>%group_by(spec2,Fight)%>%mutate(medianDPS=median(total))
#Generates all the different boxplots
p0=ggplot(ursoc.dps.filtered,aes(x=reorder(spec2,fullMedian),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Overall")
p1=ggplot(ursoc.dps.filtered%>%filter(Fight=="Nythendra"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Nythendra")
p2=ggplot(ursoc.dps.filtered%>%filter(Fight=="Il'gynoth"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Il'gynoth")
p3=ggplot(ursoc.dps.filtered%>%filter(Fight=="Renferal"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Renferal")
p4=ggplot(ursoc.dps.filtered%>%filter(Fight=="Ursoc"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Ursoc")
p5=ggplot(ursoc.dps.filtered%>%filter(Fight=="Dragons of Nightmare"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Dragons of Nightmare")
p6=ggplot(ursoc.dps.filtered%>%filter(Fight=="Cenarius"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Cenarius")
p7=ggplot(ursoc.dps.filtered%>%filter(Fight=="Xavius"),aes(x=reorder(spec2,medianDPS),y=total,color=spec2))+geom_boxplot(lwd=1)+scale_colour_manual(values=palette2)+theme(axis.text.x=element_text(angle=90,vjust=1),axis.title.x=element_blank(),text=element_text(size=16))+labs(title="Xavius")
#Combines them together into one. I use grid.arrange instead of facet_wrap because getting the ggplot to order the boxes for each fight was turning out to be problematic.
grid.arrange(p0,p1,p2,p3,p4,p5,p6,p7,nrow=8,ncol=1)
#function I borrowed for fitting regression lines and returning their slopes and intercepts
le_lin_fit <- function(dat) {
the_fit <- lm(total ~ itemLevel, dat)
setNames(data.frame(t(coef(the_fit))), c("intercept", "slope"))
}
scaling=ursoc.dps.filtered%>%filter(itemLevel>835)%>%group_by(spec2)%>%do(le_lin_fit(.))
ggplot(ursoc.dps.filtered%>%filter(itemLevel>835),aes(x=itemLevel,y=total))+geom_point()+geom_abline(data=scaling,aes(intercept = intercept,slope=slope,color=spec2),size=2)+scale_colour_manual(values=palette3)+facet_wrap(~spec2)+theme(text=element_text(size=12))
@rptaheri
Copy link

rptaheri commented Nov 2, 2016

Hey -- Nice work!

There seems to be an error in the code. I swapped in my API key and tried to run it, but I'm getting an error when attempting to rbind on this line:

merged = rbind(merged,datalist)

It seems as though the datalist that is coming back is less the 7,000 observations that is in the merged object already. Trying to debug the reason for this but having a hard time...

@JyuNyar
Copy link
Author

JyuNyar commented Nov 2, 2016

The problem was a different number of rows, because I added a difficulty column on the import data frame. This is remnant of when i was trying to automate grabbing both heroic and mythic rankings at once, but due to warcraftlogs not returning the [size] column for mythic I scrapped that idea.

It should be working fine now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment