Chess tournament cross-tables contain information about players, ratings, scores, opponents, and game results in a semi-structured text format. Although the file is readable to a person, it is not immediately suitable for analysis or database storage.
The objective of this project is to use R to read and transform the provided tournamentinfo.txt file into a structured CSV dataset. The final dataset will contain each player’s name, state, total points, pre-tournament rating, and average pre-tournament rating of the opponents faced.
The project will also validate the transformed data and perform a small exploratory data analysis before generating the final chess_tournament_results.csv file.
Data Source
The data were provided by the professor in the file tournamentinfo.txt. The file contains the results of a seven-round chess tournament with 64 players.
Each player is represented by two lines. The first line contains the player’s pairing number, name, total points, and results for each round. The second line contains the player’s state, USCF identification number, pre-tournament rating, post-tournament rating, and color played in each round.
Round results such as W 39, L 8, or D 12 identify a win, loss, or draw and the pairing number of the opponent. Codes without an opponent number, including B, H, U, and X, represent special tournament outcomes and are not used when calculating the average opponent rating.
Data Dictionary
The final CSV file contains one row for each player and the following variables:
Variable
Description
player_name
Full name of the chess player
state
Player’s state or province abbreviation
total_points
Total tournament points earned by the player
pre_rating
Player’s rating before the tournament
average_opponent_pre_rating
Average pre-tournament rating of the player’s numbered opponents
The average opponent rating is calculated by identifying the opponent pairing numbers in the round results, matching those numbers to the corresponding players, retrieving their pre-tournament ratings, and calculating the arithmetic mean.
Planned Approach
The project follows these steps:
Read all lines from tournamentinfo.txt into R.
Identify the two lines associated with each player.
Extract the pairing number, player name, state, total points, and pre-tournament rating.
Extract the numbered opponents from the seven round-result fields.
Exclude special tournament codes that do not identify an opponent.
Match each opponent number to the corresponding player’s pre-tournament rating.
Calculate and round the average opponent pre-rating for every player.
Create a tidy dataset with one row per player.
Validate the transformed data.
Confirm that Gary Hua’s average opponent pre-rating is 1605.
Export the final dataset as chess_tournament_results.csv.
Perform a small exploratory data analysis.
The original text file remains unchanged. All transformations, calculations, validations, and exports are performed reproducibly in this Quarto document.
Data Import and Initial Inspection
The required packages are loaded and the original tournament text file is read into R.
library(readr)library(dplyr)library(stringr)library(ggplot2)library(knitr)raw_lines <-read_lines("tournamentinfo.txt",progress =FALSE)file_summary <-data.frame(measure =c("Source file","Raw text lines" ),value =c("tournamentinfo.txt",length(raw_lines) ))knitr::kable( file_summary,col.names =c("Measure", "Value"),align =c("l", "l"),caption ="Initial inspection of the source file")
Initial inspection of the source file
Measure
Value
Source file
tournamentinfo.txt
Raw text lines
196
Identifying Player Records
Player records are identified by lines that begin with a pairing number followed by a vertical separator. The following line contains the player’s state and rating information.
player_line_indices <-which(str_detect( raw_lines,"^\\s*[0-9]+\\s*\\|" ))number_of_players <-length(player_line_indices)player_record_summary <-data.frame(measure ="Identified player records",value = number_of_players)knitr::kable( player_record_summary,col.names =c("Measure", "Value"),align =c("l", "r"),caption ="Player record identification summary")
Player record identification summary
Measure
Value
Identified player records
64
player_line_preview <-data.frame(pairing_number =seq_len(6),source_line =head(player_line_indices, 6))knitr::kable( player_line_preview,col.names =c("Pairing No.","Source Line" ),align =c("r", "r"),caption ="Location of the first six player records")
Location of the first six player records
Pairing No.
Source Line
1
5
2
8
3
11
4
14
5
17
6
20
Preliminary Data Inspection
The preliminary inspection confirms that the source file contains 196 text lines and 64 identifiable player records.
inspection_summary <-data.frame(measure =c("Raw text lines","Identified player records" ),value =c(length(raw_lines), number_of_players ))knitr::kable( inspection_summary,col.names =c("Measure", "Value"),align =c("l", "r"),caption ="Preliminary inspection of the tournament file")
Preliminary inspection of the tournament file
Measure
Value
Raw text lines
196
Identified player records
64
Extracting Basic Player Information
The first transformation extracts the pairing number, player name, state, total points, and pre-tournament rating for each player.
The seven round fields contain game results and, when applicable, the pairing number of the opponent. Special results without an opponent number are converted to missing values and excluded.
Each opponent pairing number is matched to the corresponding player’s pre-tournament rating. The identified ratings are averaged and rounded to the nearest whole number.
The required variables are selected and arranged into the final dataset. Validation checks confirm the number of players, required columns, missing values, duplicate pairing numbers, valid opponent references, and Gary Hua’s expected result.
The tournament included 64 players. The mean pre-tournament rating was approximately 1378.5, while the median was 1407. Ratings ranged from 377 to 1794. The overall mean opponent rating was approximately 1378.6.
Player Rating and Opponent Strength
The following visualization compares each player’s pre-tournament rating with the average pre-tournament rating of the opponents faced.
The original semi-structured tournament cross-table was successfully transformed into a tidy dataset containing 64 player records and the five variables required by the assignment.
The validation found no missing required values, duplicate pairing numbers, or invalid opponent references. Gary Hua’s calculated average opponent pre-rating was 1605, which matches the expected assignment result.
The completed dataset was exported as chess_tournament_results.csv and successfully read back into R with its 64 rows, five columns, and original column names preserved.
Expected Output
The generated file is:
chess_tournament_results.csv
The first record is:
Measure
Value
Player name
Gary Hua
State
ON
Total points
6.0
Pre-tournament rating
1794
Average opponent pre-rating
1605
Deliverables
The completed project includes:
tournamentinfo.txt
DATA607-Project1-Chess-Tournament-Code-Base.qmd
DATA607-Project1-Chess-Tournament-Code-Base.html
chess_tournament_results.csv
AI Use
ChatGPT was used to help interpret the assignment requirements, organize the workflow, improve the English writing, explain the tournament cross-table structure, and provide coding guidance. I ran the code, reviewed the transformed data, validated the results, and confirmed the conclusions myself.