SAS Optimization, and SAS Simulation Studio

turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-15-2015 02:42 PM

Hi,

I would like to program an "Elo" rating in SAS to rate sports teams. The Elo rating was originally developed to rate chess players. I would like this one to work as follows:

- Each team starts off with an initial rating of 1,000 points.
- For each match, each team contributes 5% of their current rating to the "Pot"
- The winning team collects the pot and that amount is added to the it's new (post match) rating
- The losing team does not take anything from the pot and their rating will decrease by how much they contributed
- If there is a tie, the pot will be split equally between to the two teams.

Example

- Lets say we have 3 teams, Team A, B and C
- First match is A v B. Each team's initial rating is 1,000 and they contribute 5% of that (50 points) each to the pot
- Team A wins and collects the pot. Their new rating is 1,050. Team B lose so take nothing, just lose the 50 points they contributed so their new rating is 950.
- Next match is B v C. B's pre match rating is 950 and they contribute 5% of that to the pot (48). It's team C's first match so their pre match rating is 1,000 and they contribute 5% (50) to the pot.
- Team B win and collect the pot so their new rating is 1,048. Team C lose so their rating decreases by the 50 they contributed. Their post match rating is 950.
- So at this point the team rating would read as follows:

Team A 1,050

Team B 1,048

Team C 950

See below the variables in my dataset (along with first few lines of sample data)

Date Team 1 Team 2 Winner

01jan2014 Team A Team B Team A

05jan2014 Team B Team C Team B

Thanks

cxkev182

Accepted Solutions

Solution

01-16-2015
04:24 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to cxkev182

01-16-2015 04:24 AM

I don't understand.

1)

"The first match is A v B. Both of their pre match rating is 1,000 so they each contribute 5% of their rating to the pot (50 points each.)

Team A wins so their rating increases to 1,050. Team B loses so their rating decreases to 950."

TeamA would be 1,050( take 50 from TeamB). TeamB would be 950(lost 50).

2)

"The next match is B v C. B's current rating is 950 and they contribute 5% of that (48 points) to the point. This is C's first match so their rating is 1,000. They contribute 5% (50 points) to the pot."

TeamB would be 950+50(take 50 from TeamC) ?? TeamC would be 950(lost 50). ??

Why TeamB would be Team B 950+50+48= 1,048 ? That is right ?

Assuming the first scenario is right .

data have;

input Date : date9. ( Team1 Team2 Winner ) (& $);

format date date9.;

cards;

01jan2014 Team A Team B Team A

05jan2014 Team B Team C Team B

;

run;

data _null_;

if _n_ eq 1 then do;

length team $ 80;

declare hash h();

h.definekey('team');

h.definedata('team','score');

h.definedone();

end;

set have end=last;

retain score 1000;

team=team1;h.replace();

team=team2;h.replace();

if last then h.output(dataset:'team');

run;

data _null_;

if _n_ eq 1 then do;

if 0 then set team;

declare hash h(dataset:'team');

h.definekey('team');

h.definedata('team','score');

h.definedone();

end;

set have end=last;

if winner=team1 then do;

h.find(key:team2);get=score*0.05;score=score-get; h.replace();

h.find(key:team1);score=score+get;h.replace();

end;

else if winner=team2 then do;

h.find(key:team1);get=score*0.05;score=score-get; h.replace();

h.find(key:team2);score=score+get;h.replace();

end;

if last then h.output(dataset:'want');

run;

Xia Keshan

All Replies

Solution

01-16-2015
04:24 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to cxkev182

01-16-2015 04:24 AM

I don't understand.

1)

"The first match is A v B. Both of their pre match rating is 1,000 so they each contribute 5% of their rating to the pot (50 points each.)

Team A wins so their rating increases to 1,050. Team B loses so their rating decreases to 950."

TeamA would be 1,050( take 50 from TeamB). TeamB would be 950(lost 50).

2)

"The next match is B v C. B's current rating is 950 and they contribute 5% of that (48 points) to the point. This is C's first match so their rating is 1,000. They contribute 5% (50 points) to the pot."

TeamB would be 950+50(take 50 from TeamC) ?? TeamC would be 950(lost 50). ??

Why TeamB would be Team B 950+50+48= 1,048 ? That is right ?

Assuming the first scenario is right .

data have;

input Date : date9. ( Team1 Team2 Winner ) (& $);

format date date9.;

cards;

01jan2014 Team A Team B Team A

05jan2014 Team B Team C Team B

;

run;

data _null_;

if _n_ eq 1 then do;

length team $ 80;

declare hash h();

h.definekey('team');

h.definedata('team','score');

h.definedone();

end;

set have end=last;

retain score 1000;

team=team1;h.replace();

team=team2;h.replace();

if last then h.output(dataset:'team');

run;

data _null_;

if _n_ eq 1 then do;

if 0 then set team;

declare hash h(dataset:'team');

h.definekey('team');

h.definedata('team','score');

h.definedone();

end;

set have end=last;

if winner=team1 then do;

h.find(key:team2);get=score*0.05;score=score-get; h.replace();

h.find(key:team1);score=score+get;h.replace();

end;

else if winner=team2 then do;

h.find(key:team1);get=score*0.05;score=score-get; h.replace();

h.find(key:team2);score=score+get;h.replace();

end;

if last then h.output(dataset:'want');

run;

Xia Keshan

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to cxkev182

01-16-2015 04:01 PM

I developed other solution and I got the same result gotten by Xia-Keshan:

It can be easily generalized includying more teams in the Array and updating the do's. I assume a null value of winner when the result is a draw:

data games;

infile cards truncover;

input date date9. team1 $ team2 $ winner $ ;

format date date9.;

cards;

01jan2014 Team_A Team_B Team_A

05jan2014 Team_B Team_C Team_B

06jan2014 Team_C Team_A

;

run;

data winn_loss(drop=team;

set games;

if winner = ' ' then do;

winner=team1;

losser=team1;

end;

else if winner = team1 then do;

losser=team2;

end;

else do;

winner=team2;

losser=team1;

end;

run;

data want(drop=i: pot;

set winn_loss;

array team[3] Team_A Team_B Team_C (3*1000);

i_winn=0;

i_loss=0;

do i=1 to 3 while (i_winn=0);

if vinarrayx(winner) and vname(team*)=winner then i_winn=i;*

end;

do i=1 to 3 while (i_loss=0);

if vinarrayx(losser) and vname(team*)=losser then i_loss=i;*

end;

pot_win=round(team[i_winn]*0.05);

pot_los=round(team[i_loss]*0.05);

team[i_winn]=team[i_winn]+pot_los;

team[i_loss]=team[i_loss]-pot_los;

run;

CTorres

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to CTorres

01-17-2015 04:54 AM

That's great thanks for your help and apologies for my typo in the original question. I wish I could mark both as correct answer.