Date: Thu, 27 Dec 2007 11:16:03 -0500
Reply-To: Collin Elliot <collin.elliot@ITRON.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Collin Elliot <collin.elliot@ITRON.COM>
Subject: Re: Completely Non-Work Related...
Here's a a crude attempt to get at the to real issue of interest for the
fantasy football league. I would NOT recommend running it, as portions of
it take a lot of memory (probably the biggest flaw). It could also
probably be improved greatly by incorporating some recent posts, but it's
what I was able to throw together over the break.
/* Create a round-robin scheme that creates matchups for weeks one through
9 */
/* and then repeats for weeks 10 through 13, as it did in our league. */
data playerRotation(drop = i j);
array slot_{9}; /* Nine of the ten will rotate each week. */
slot_10 = 10; /* The tenth player will stay in the same position.
*/
do i = 0 to 8; /* This is really just the increment you want to
rotate each week. */
do j = 1 to 9;
slot_(j) = mod(j + i, 9);
if slot_(j) = 0 then slot_(j) = 9;
week = i + 1;
mergeWeek = mod(week, 9);
end;
output;
end;
run;
/* Create a template of week one through the number of weeks in the
fantasy season. */
data template;
do week = 1 to 13;
mergeWeek = mod(week, 9); /* This is so that weeks later
than nine will */
output; /* have the
appropriate week merged on. */
end;
run;
/* Merge the two. . . */
proc sql;
CREATE TABLE matchups(drop = mergeWeek) AS
SELECT a.week "Week of Fantasy Season",
b.*
FROM template AS a
LEFT JOIN playerRotation AS b
ON a.mergeWeek = b.mergeWeek
ORDER BY week;
quit;
/* There are 3,628,800 (10!) possible ways the ten teams could have been
ordered */
/* in the first week of play. While the permutations will produce
duplicate */
/* matchups (4 vs. 5 or 5 vs. 4, for example), we'll not worry about
those. */
/* Use PROC PLAN as an easy way of creating the different possible week
one orders. */
proc plan;
factors permNum = 3628800 ordered
team = 10 perm / noprint;
output out = weekOneOrders ;
quit;
data weekOneOrders2;
retain pairOrder;
set weekOneOrders;
by permNum;
/* Need to establish an order to the teams in each permutation or
else on sort will */
/* kill the data set. */
if first.permNum then pairOrder = 1;
else pairOrder = pairOrder + 1;
tranId = "team_"||strip(put(pairOrder, best.));
run;
proc transpose data = weekOneOrders2
out = weekOneOrders3;
by permNum;
var team;
id tranId;
run;
%let sampleLimit = 10; /* Use something small to test. . .*/
data weekOneOrders4;
set weekOneOrders3;
keepMe = ranUni(9);
if keepMe <= &sampleLimit;
run;
/* Merge the possible week one orders with the possible rotations. . . */
proc sql;
CREATE TABLE pairingPerms AS
SELECT *
FROM matchups,
weekOneOrders4
ORDER BY permNum, week;
quit;
data pairingPerms2;
set pairingPerms;
array team_{10};
array slot_{10};
array plyr_{10};
do i = 1 to 10;
plyr_(i) = team_(slot_(i));
end;
drop team_: slot_: _name_ i;
run;
/* Create a dataset with the actual scores for each team in all weeks of
competition. */
data actualScores;
infile datalines dlm = "|";
input team :$30. matchup score week draftOrder teamNum;
tranId = "score_"||strip(put(teamNum, best.));
datalines;
Shart Attack!|1|152.27|1|5|1
Dementor's Kiss|1|86.25|1|9|2
TeamCanHasChezburger|2|121.42|1|6|3
Raider Nation|2|144.42|1|1|4
Mangs|3|142.88|1|4|5
Ecofluent|3|143.88|1|7|6
whinemakers|4|162.74|1|8|7
Patastrophe|4|137.23|1|10|8
SmougCanHazShartbrgr|5|121|1|2|9
This Year's Rick|5|119.56|1|3|10
Shart Attack!|1|124.42|2|5|1
TeamCanHasChezburger|1|177.16|2|6|3
Raider Nation|2|153.24|2|1|4
This Year's Rick|2|127.6|2|3|10
Mangs|3|140.98|2|4|5
Dementor's Kiss|3|150.92|2|9|2
whinemakers|4|162.89|2|8|7
Ecofluent|4|145.42|2|7|6
SmougCanHazShartbrgr|5|119.1|2|2|9
Patastrophe|5|148.34|2|10|8
Shart Attack!|1|139.96|3|5|1
Raider Nation|1|111.48|3|1|4
TeamCanHasChezburger|2|154.64|3|6|3
Mangs|2|118.54|3|4|5
whinemakers|3|139.42|3|8|7
Dementor's Kiss|3|157.41|3|9|2
SmougCanHazShartbrgr|4|124.57|3|2|9
Ecofluent|4|210.59|3|7|6
Patastrophe|5|171.8|3|10|8
This Year's Rick|5|175.36|3|3|10
Shart Attack!|1|138.75|4|5|1
This Year's Rick|1|138.28|4|3|10
TeamCanHasChezburger|2|100.5|4|6|3
whinemakers|2|128.05|4|8|7
Raider Nation|3|105.44|4|1|4
Mangs|3|139.82|4|4|5
SmougCanHazShartbrgr|4|105.34|4|2|9
Dementor's Kiss|4|128.46|4|9|2
Patastrophe|5|135.68|4|10|8
Ecofluent|5|132.29|4|7|6
Shart Attack!|1|125.45|5|5|1
Mangs|1|120.6|5|4|5
TeamCanHasChezburger|2|153.48|5|6|3
SmougCanHazShartbrgr|2|97.72|5|2|9
Raider Nation|3|62.84|5|1|4
whinemakers|3|91.75|5|8|7
Patastrophe|4|130.84|5|10|8
Dementor's Kiss|4|116.54|5|9|2
Ecofluent|5|108.85|5|7|6
This Year's Rick|5|122.34|5|3|10
Shart Attack!|1|185|6|5|1
whinemakers|1|106.23|6|8|7
TeamCanHasChezburger|2|161.22|6|6|3
Patastrophe|2|125.68|6|10|8
Raider Nation|3|124.64|6|1|4
SmougCanHazShartbrgr|3|127.39|6|2|9
Mangs|4|130.26|6|4|5
This Year's Rick|4|155.3|6|3|10
Ecofluent|5|111.11|6|7|6
Dementor's Kiss|5|144.4|6|9|2
Shart Attack!|1|142.59|7|5|1
SmougCanHazShartbrgr|1|100.07|7|2|9
TeamCanHasChezburger|2|82.1|7|6|3
Ecofluent|2|201.98|7|7|6
Raider Nation|3|105.4|7|1|4
Patastrophe|3|137.49|7|10|8
Mangs|4|119.48|7|4|5
whinemakers|4|169.83|7|8|7
Dementor's Kiss|5|130.9|7|9|2
This Year's Rick|5|173.06|7|3|10
Shart Attack!|1|162.07|8|5|1
Patastrophe|1|157.91|8|10|8
TeamCanHasChezburger|2|115.1|8|6|3
Dementor's Kiss|2|129.58|8|9|2
Raider Nation|3|128.94|8|1|4
Ecofluent|3|99.57|8|7|6
Mangs|4|159.42|8|4|5
SmougCanHazShartbrgr|4|51.14|8|2|9
whinemakers|5|118.38|8|8|7
This Year's Rick|5|133.74|8|3|10
Shart Attack!|1|213.95|9|5|1
Ecofluent|1|164.26|9|7|6
TeamCanHasChezburger|2|53.14|9|6|3
This Year's Rick|2|160.62|9|3|10
Raider Nation|3|117.72|9|1|4
Dementor's Kiss|3|170|9|9|2
Mangs|4|117.86|9|4|5
Patastrophe|4|190.74|9|10|8
whinemakers|5|145.25|9|8|7
SmougCanHazShartbrgr|5|83.15|9|2|9
Shart Attack!|1|117.8|10|5|1
Dementor's Kiss|1|80.18|10|9|2
TeamCanHasChezburger|2|97.66|10|6|3
Raider Nation|2|124.42|10|1|4
Mangs|3|124.34|10|4|5
Ecofluent|3|171.36|10|7|6
whinemakers|4|91.52|10|8|7
Patastrophe|4|172.32|10|10|8
SmougCanHazShartbrgr|5|103.53|10|2|9
This Year's Rick|5|119.76|10|3|10
Shart Attack!|1|172.63|11|5|1
TeamCanHasChezburger|1|147.45|11|6|3
Raider Nation|2|133.86|11|1|4
This Year's Rick|2|180.7|11|3|10
Mangs|3|99.38|11|4|5
Dementor's Kiss|3|167.58|11|9|2
whinemakers|4|135.77|11|8|7
Ecofluent|4|172.02|11|7|6
SmougCanHazShartbrgr|5|116.23|11|2|9
Patastrophe|5|160.78|11|10|8
Shart Attack!|1|105.67|12|5|1
Raider Nation|1|151.72|12|1|4
TeamCanHasChezburger|2|144.52|12|6|3
Mangs|2|135.2|12|4|5
whinemakers|3|176.14|12|8|7
Dementor's Kiss|3|197.2|12|9|2
SmougCanHazShartbrgr|4|139.45|12|2|9
Ecofluent|4|143.54|12|7|6
Patastrophe|5|85.73|12|10|8
This Year's Rick|5|133.06|12|3|10
Shart Attack!|1|146.8|13|5|1
This Year's Rick|1|106.63|13|3|10
TeamCanHasChezburger|2|117.14|13|6|3
whinemakers|2|108.99|13|8|7
Raider Nation|3|148.08|13|1|4
Mangs|3|133.51|13|4|5
SmougCanHazShartbrgr|4|156.76|13|2|9
Dementor's Kiss|4|120.04|13|9|2
Patastrophe|5|157.16|13|10|8
Ecofluent|5|122.6|13|7|6
;
run;
proc sql;
CREATE TABLE teamFmt AS
SELECT DISTINCT teamNum AS start, team AS label,
"team" AS fmtName, "N" AS type
FROM actualScores;
quit;
proc format cntlin = teamFmt;
run;
proc sort data = actualScores;
by week teamNum;
run;
proc transpose data = actualScores
out = actualScoresTrans;
by week;
var score;
id tranId;
run;
proc sql;
CREATE TABLE fullPairings AS
SELECT *
FROM pairingPerms2 AS a
LEFT JOIN actualScoresTrans AS b
ON a.week = b.week
ORDER BY a.permNum, a.week;
quit;
data fullResults(drop = _:);
length week 8. permNum 8. pair_1 - pair_5 $9 scores_1 - scores_5
$18;
set fullPairings;
array plyr_{10};
array score_{10};
array pair_{5} $;
array scores_{5} $;
array winner_{5};
do j = 1 to 5;
pair1 = min(plyr_(j), plyr_(abs(j - 11)));
pair2 = max(plyr_(j), plyr_(abs(j - 11)));
pair_(j) = strip(put(pair1, best.))||" vs. "||strip(put
(pair2, best.));
score1 = score_(pair1);
score2 = score_(pair2);
scores_(j) = strip(put(score1, 8.2))||" to "||strip(put
(score2, 8.2));
if score1 > score2 then winner_(j) = pair1;
else winner_(j) = pair2;
end;
run;
proc transpose data = fullResults
out = allWinners;
by permNum week;
var winner_1 - winner_5;
run;
proc summary data = allWinners nway;
class permNum col1;
var week;
output out = records n = wins;
run;
proc sort data = records;
by permNum descending wins;
run;
data records2;
retain place;
set records(rename = (col1 = team));
by permNum descending wins;
if first.permNum then place = 1;
else place = place + 1;
run;
proc freq data = records2 noprint;
format team team.;
table team * place / out = records3;
run;
proc sql;
CREATE TABLE finalResults AS
SELECT put(team, team.) AS teamName "Team Name", team "Team
Number",
place "Finish Place",
count AS timesInPlace "Times in Place",
count / sum(count) AS pct format percent8.1 "Percent of
Total"
FROM records3
GROUP BY team
ORDER BY team, place;
quit;