Two hobbys combined
I’ve been playing table hockey for little over 8 years now and since the very beginning I’ve been interested in statistics and different software we use while organising tournaments and seasons. I’ve been writing few softwares for tournament/season statistics with Java and Perl so when I started learning R, table hockey statistics were the number one choice for data to start learning with.
Finnish Table Hockey Association organizes 7 tournaments per year as a ranking system and to date there has been 125 tournaments with over 600 different players participating so it gave me good starting point for my first R script.
Data is 125 txt-files with bare names listed in order of placements. As I didn’t (and yet don’t) know how to create data frames out of those, I created small Java program to create csv-files for me so it was easy to move on to R.
Placements.java
/** Creates CSV files for each player on placement files
* @author rocknrblog.wordpress.com
* @version 0.9b
* License: This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
*/
import java.io.*;
import java.util.*;
public class Placements {
private static Scanner RD = new Scanner(System.in);
private static ArrayList<Player> players = new ArrayList<Player>();
private static ArrayList<Player> temporary = new ArrayList<Player>();
public static void main(String[] args) {
System.out.println("Nro of tournaments:");
int nroOfTournaments = RD.nextInt();
for (int i = 1; i <= nroOfTournaments; i++) {
createPlayersList(i + ".txt");
System.out.println("Players read from file " + i + ".txt");
}
for (int i = 1; i <= nroOfTournaments; i++) {
readPlayers(i + ".txt");
System.out.println("Placements read from file " + i + ".txt");
}
writePlayers();
}
/**
* Reads a file given as argument and reads all the player names to a ArrayList
* @.pre filename != null
*/
public static void createPlayersList(String filename) {
try {
BufferedReader bufReader = new BufferedReader(
new InputStreamReader(
new FileInputStream(filename)));
int i = 0;
while(bufReader.ready()) {
String line = bufReader.readLine();
if (!isFound(line, players)) {
players.add(new Player(line));
}
i++;
}
bufReader.close();
}
catch(Exception e) {
System.out.println("Error: " + e);
}
}
/**
* Reads players from placement lists to arraylist with placements
* @.pre filename != null
*/
private static void readPlayers(String filename) {
for (int i = 1; i <= players.size(); i++) {
Player p = players.get(i-1);
int sijoitus = getPlacement(p.name(), filename);
p.addPlace(sijoitus);
}
}
/**
* Returns placement of wanted player on wanted file
* @.pre player != null & isFound(player, players) & fname!=null
*/
private static int getPlacement(String player, String fname) {
int i = 0;
try {
BufferedReader bufReader = new BufferedReader(
new InputStreamReader(
new FileInputStream(fname)));
i = 1;
while(bufReader.ready()) {
String line = bufReader.readLine();
if (player.equals(line)) {
return i;
}
i++;
}
bufReader.close();
return 0;
}
catch(Exception e) {
System.out.println("ny tuli virhe: " + e);
}
return i;
}
/**
* Writes players' placement information into csv-file for R
* @.post a file named [player_name].csv is created
*/
private static void writePlayers() {
try {
for (int k = 0; k < players.size(); k++) {
String filename = players.get(k).name() + ".csv";
FileOutputStream printStream = new FileOutputStream(new File(filename));
PrintWriter writer = new PrintWriter(printStream, true);
writer.println("turnaus, sijoitus");
writer.print(players.get(k));
System.out.println(players.get(k).name() + " kirjattu");
writer.close();
}
}
catch (IOException e) {
System.out.println(e);
}
}
/**
* Looks if player is already found on the list
* @.pre name != null
*/
private static boolean isFound(String name, ArrayList<Player> list) {
for (int j = 0; j < list.size(); j++) {
if (list.get(j).name().equals(name))
return true;
}
return false;
}
/**
* Gets player from the list
* @.pre name != null
*/
private static Player getPlayer(String name) {
for (int j = 0; j < players.size(); j++) {
if (players.get(j).name().equals(name))
return players.get(j);
}
return null;
}
}
After this I wanted to have a program to combine multiple players to one csv-file for easy use on R:
CombineCSV.java
/** Creates a combined CSV file of chosen players
* @author rocknrblog.wordpress.com
* @version 0.9b
* License: This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
*/
import java.io.*;
import java.util.*;
public class CombineCSV {
private static ArrayList<String> players = new ArrayList<String>();
private static ArrayList<Integer> placements = new ArrayList<Integer>();
private static ArrayList<Integer> tournaments = new ArrayList<Integer>();
/**
* If ran without command line parameters, it will read players from file 'players.txt'. If run with clp, it'll choose those players and create 'allplayers.csv' with combined data
*/
public static void main(String[] args) {
if(args.length == 0) {
readPlayers();
}
else {
for (int i =0; i < args.length; i++) {
players.add(args[i]);
}
}
readOriginals();
writeNewCSV();
}
/**
* Reads players from players.txt file
*/
private static void readPlayers() {
try {
String filename = "players.txt";
BufferedReader bufReader = new BufferedReader(
new InputStreamReader(
new FileInputStream(filename)));
while(bufReader.ready()) {
players.add(bufReader.readLine());
}
}
catch (Exception e) {
System.out.print("readPlayers: " + e);
}
}
/**
* Reads the player's original CSV file
*/
private static void readOriginals() {
try {
for (int i = 0; i < players.size(); i++) {
String filename = players.get(i) + ".csv";
BufferedReader bufReader = new BufferedReader(
new InputStreamReader(
new FileInputStream(filename)));
int k = -1;
while(bufReader.ready()) {
k++;
String line = bufReader.readLine();
String[] data = line.split(",");
if (k == 0) continue;
if (i == 0)
tournaments.add(Integer.parseInt(data[0]));
placements.add(Integer.parseInt(data[1]));
}
}
}
catch(Exception e) {
System.out.println("ny tuli virhe: " + e);
}
}
/**
* Writes a new CSV file with combined data
*/
private static void writeNewCSV() {
try {
String filename = "allPlayers.csv";
FileOutputStream printStream = new FileOutputStream(new File(filename));
PrintWriter writer = new PrintWriter(printStream, true);
/* Creating a caption line */
String caption = "tournament,";
for (int i=1; i <= players.size(); i++) {
System.out.println(players.get(i-1));
caption += players.get(i-1);
if (i < players.size()) caption += ",";
}
writer.println(caption);
int s = placements.size() / players.size() ;
for (int k = 1; k <= tournaments.size(); k++) {
String line = k + ",";
for (int p = k-1; p < placements.size(); p+= s) {
if (placements.get(p) != 0) {
line += placements.get(p) + ",";
}
else line += "NA,";
}
line = line.substring(0,line.length()-1);
writer.print(line);
if (k < tournaments.size()) { writer.print("\n"); }
}
writer.close();
}
catch (Exception e) { System.out.println("writeNewCSV: " + e);} }
}
}
After this we get to fun stuff and to R:
## Creates plot of players' progress on tournaments
# Load ggplot2 for creating the plot
library("ggplot2")
# Read the data
tournamentdata <- read.csv('allPlayers.csv')
# Combine data according to column "tournament"
plotdata <- melt(tournamentdata, id="tournament")
# Theme the plot background to be white instead of default gray
th = theme_bw()
th$panel.background
theme_rect(fill = "white", colour = NA)
th$panel.background = theme_rect(fill = "white", colour = NA)
theme_set(th)
#Define plot title
mainTitle <- "Placements on FTHA Ranking tournaments"
#Create the plot with reversed y-axis (for the 1st place to be on the top) and two lines (one on 8th place for the playoffs and other on 16th place for the final group)
plot <- ggplot(plotdata, aes(x=tournament, y=value, color=variable)) + geom_point() + geom_line(data=plotdata) + scale_y_reverse("Placement") + geom_hline(yintercept=8, colour="red", size=1.2) + geom_hline(yintercept=16, colour="blue", size=1.2) + scale_x_continuous("Tournament", breaks=c(min(plotdata$tournament):max(plotdata$tournament) + coord_cartesian(xlim=c(0,127), ylim=c(0,70)) + opts(title = mainTitle)
# Print out the plot
print(plot)
Plot:
