BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
cxkev182
Fluorite | Level 6

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

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User

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

View solution in original post

3 REPLIES 3
Ksharp
Super User

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

CTorres
Quartz | Level 8

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

cxkev182
Fluorite | Level 6

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.

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

Register now!

Discussion stats
  • 3 replies
  • 1996 views
  • 3 likes
  • 3 in conversation