Browsed by
Month: August 2016

An Ideal Home Media Setup

An Ideal Home Media Setup

I love movies and have a bunch of them but I didn’t want to always have to go upstairs and grab a DVD/Bluray each time I needed access to my movies or any other media that I have so I began searching for an ideal home media setup. I think I’ve found it and figured I’d write about it.

Everything  is moving towards streaming so of course you need a streaming device on all your home tv’s. You can do this with a Smart TV(all TV’s are smart now, although the independent streaming devices are usually much better), Roku, Amazon Fire Stick, Apple TV, Chromecast, XBox One etc… I went with Roku it’s one of the best rated streaming devices and supports numerous apps. You can get a  simple Roku Stick for 49.99 at Best Buy. The sticks are also very convenient for travel because you can stick them right into the HDMI port at your hotel and get access to all your streaming apps.

Now that you have your streaming device what app should you use to host your media at home. After doing some research I went with Plex  it has apps on most streaming devices and will essentially turn your movie collection into a Netflix like interface. Plex is setup in your traditional client server setup. You’ll need to run Plex server on your laptop/desktop/NAS device. Your media should be accessible from the machine that is hosting the Plex server. Plex server will provide you with a Web Interface that you’ll be able to add libraries to representing the directories your media is stored at. Assuming your movies have appropriate names(i.e. a title representing the movie) Plex will find the movie and all the necssary metadata for you. For optimal performance you should follow the suggested naming format:

Once you have the Plex server running all you’ll need to do is install the Plex client on your favorite streaming device. The Plex client then displays all your media in a well organized format for your viewing pleasure.

With this setup you’ll be able to sit anywhere in your home and have access to all your media. With the right setup you can even have access to your home media remotely or share your home media with family and friends through Plex.

 

 

Jackson based JAX-RS Providers(JSON, XML, CSV) Example

Jackson based JAX-RS Providers(JSON, XML, CSV) Example

This blog post discusses returning multiple data formats from your RESTFul endpoints using Jackson JAX-RS providers. Jackson provides a lot of providers that you can see here . The providers allow you to return a POJO(plain old java object) from your REST annotated methods and give back the appropriate media type. Jackson also gives you the ability make your own Entity Providers. Documentation for how to do that is here below I’ll show a generic way to provide CSV’s along with XML and JSON.

Pom

Sample Model Objects

REST Resource

Custom Entity Provider

Configuration

Instructions

Screen Shots

Pom

[code language=”xml”]
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>datadidit.helpful.hints</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>jetty-cxf</artifactId>
<name>jetty-cxf</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
</plugin>
</plugins>
</build>
</project>
[/code]

Model

Simple model object.

[code language=”java”]
package datadidit.helpful.hints.csv.test.model;

import java.util.Date;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="SimpleSample")
public class SimpleSample {
private String firstName;

private String lastName;

private Date dob;

public SimpleSample(){}

public SimpleSample(String firstName, String lastName, Date dob){
this.dob = dob;
this.firstName = firstName;
this.lastName = lastName;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public Date getDob() {
return dob;
}

public void setDob(Date dob) {
this.dob = dob;
}

}
[/code]

POJO with a Data Structure(Map) embedded in it. This implements the CSVTransformer interface so the CSV Entity Provider below can know how to flatten the POJO.

[code language=”java”]
package datadidit.helpful.hints.csv.test.model;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.annotation.XmlRootElement;

import datadidit.helpful.hints.csv.provider.CSVTransformer;

@XmlRootElement(name="ComplexSample")
public class ComplexSample implements CSVTransformer{
private String studentId;

private Map<String, String> grades;

public ComplexSample(){}

public ComplexSample(String studentId, Map<String, String> grades){
this.studentId = studentId;
this.grades = grades;
}

@Override
public Map<?, ?> flatten() {
Map<String, Object> myMap = new HashMap<>();
myMap.put("studentId", studentId);
myMap.putAll(grades);

return myMap;
}

public String getStudentId() {
return studentId;
}

public void setStudentId(String studentId) {
this.studentId = studentId;
}

public Map<String, String> getGrades() {
return grades;
}

public void setGrades(Map<String, String> grades) {
this.grades = grades;
}

}
[/code]

REST

REST Endpoint defining URLs for the Web Service.

[code language=”java”]
package datadidit.helpful.hints.rest;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import datadidit.helpful.hints.csv.provider.CSVTransformer;
import datadidit.helpful.hints.csv.test.model.ComplexSample;
import datadidit.helpful.hints.csv.test.model.SimpleSample;

@Path("CustomProvider")
public class CXFSampleResource {
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, "application/csv"})
@Path("test/{caseToUse}")
public List<?> doSomething(@PathParam("caseToUse") @DefaultValue("simple") String caseToUse){
List<Object> test = new ArrayList<>();
if(caseToUse.equalsIgnoreCase("simple")){
for(SimpleSample samp : this.generateSimpleSample())
test.add(samp);
}else{
for(ComplexSample samp : this.generateComplexSample())
test.add(samp);
}

System.out.println("Hello: "+test);
return test;
}

public List<SimpleSample> generateSimpleSample(){
List<SimpleSample> samples = new ArrayList<>();
samples.add(new SimpleSample("hello", "world", new Date()));
samples.add(new SimpleSample("hello", "chad", new Date()));
samples.add(new SimpleSample("hello", "marcus", new Date()));
samples.add(new SimpleSample("hello", "joy", new Date()));
samples.add(new SimpleSample("hello", "mom", new Date()));

return samples;
}

public List<ComplexSample> generateComplexSample(){
Map<String, String> grades = new HashMap<>();
grades.put("Class1", "A");
grades.put("Class2", "B");
grades.put("Class3", "C");
grades.put("Class4", "D");

List<ComplexSample> samples = new ArrayList<>();
samples.add(new ComplexSample(UUID.randomUUID().toString(), grades));
samples.add(new ComplexSample(UUID.randomUUID().toString(), grades));
samples.add(new ComplexSample(UUID.randomUUID().toString(), grades));
samples.add(new ComplexSample(UUID.randomUUID().toString(), grades));

return samples;
}
}
[/code]

Custom Entity Provider

Generic Interface that provides method for flattening a POJO so that the POJO
can be converted to a csv.

[code language=”java”]
package datadidit.helpful.hints.csv.provider;

import java.util.Map;

public interface CSVTransformer {
/**
* Utility method to Flatten POJO so that it can be converted into a CSV
* @return
*/
Map<?,?> flatten();
}
[/code]

Generic Entity Provider to generate a CSV file from a List of POJOs. Uses Jacksons CSV dataformat.

[code language=”java”]
package datadidit.helpful.hints.csv.provider;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;

import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.csv.CsvSchema.Builder;

@Produces("application/csv")
public class CSVBodyWriter implements MessageBodyWriter<Object>{
Logger logger = Logger.getLogger(CSVBodyWriter.class.getName());

public long getSize(Object myCollectionOfObjects, Class type, Type genericType, Annotation[] annotations,
MediaType arg4) {
return 0;
}

public boolean isWriteable(Class type, Type genericType, Annotation[] annotations,
MediaType arg3) {
return true;
}

public void writeTo(Object myCollectionOfObjects, Class type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityHeaders)
throws IOException, WebApplicationException {
//Whatever makes it in here should be a list
List<?> myList = new ArrayList<>();
if(myCollectionOfObjects instanceof List && ((myList=(List<?>)myCollectionOfObjects).size()>0)){
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = null;

/*
* If it’s not a flat POJO must implement
* CSVTransformer
*/
if(implementsCSVTransformer(myList.get(0).getClass())){
Class[] params = {};
try {
Method meth = CSVTransformer.class.getDeclaredMethod("flatten", params);

/*
* Create a new list using the toMap() function
*/
List<Map<String, ?>> listOfMaps = new ArrayList<>();
Set<String> headers = null;
for(Object obj : myList){
Map<String, ?> keyVals = (Map<String, ?>) meth.invoke(obj, params);

if(schema==null){
schema = this.buildSchemaFromKeySet(keyVals.keySet());
headers = keyVals.keySet();
}

//Validate that latest headers are the same as the original ones
if(headers.equals(keyVals.keySet()))
listOfMaps.add(keyVals);
else
logger.warning("Headers should be the same for each objects in the list, excluding this object "+keyVals);
}

csvMapper.writer(schema).writeValue(entityHeaders, listOfMaps);
} catch (Exception e) {
throw new IOException("Unable to retrieve flatten() "+e.getMessage());
}
}else{
schema = csvMapper.schemaFor(myList.get(0).getClass()).withHeader();
csvMapper.writer(schema).writeValue(entityHeaders, myList);
}
}else if(myList.isEmpty()){
logger.warning("Nothing in list to convert to CSV….");
entityHeaders.write(myList.toString().getBytes(Charset.forName("UTF-8")));
}else{
throw new IOException("Not in proper format must pass a java.util.List to use this MessageBodyWriter…");
}
}

public CsvSchema buildSchemaFromKeySet(Set<String> keySet){
Builder build = CsvSchema.builder();
for(String field : keySet){
build.addColumn(field);
}
CsvSchema schema = build.build().withHeader();
return schema;
}

public Boolean implementsCSVTransformer(Class arg1){
Class[] interfaces = arg1.getInterfaces();
for(Class aClass : interfaces){
if(aClass.getName().equals(CSVTransformer.class.getName()))
return true;
}

return false;
}
}
[/code]

Configuration

This xml file configures the CXF servlet, extension mappings and providers for your Web Service to use. Some good docs on this configuration file can be found here.

[code language=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>CSV Provider Test</display-name>
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
<!– Name of the resource –>
<init-param>
<param-name>jaxrs.serviceClasses</param-name>
<param-value>
datadidit.helpful.hints.rest.CXFSampleResource,
</param-value>
</init-param>
<!– Name of the providers –>
<init-param>
<param-name>jaxrs.providers</param-name>
<param-value>
com.fasterxml.jackson.jaxrs.xml.JacksonJaxbXMLProvider,
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider,
datadidit.helpful.hints.csv.provider.CSVBodyWriter
</param-value>
</init-param>
<!– Name of the extensions –>
<init-param>
<param-name>jaxrs.extensions</param-name>
<param-value>
csv=application/csv
json=application/json
xml=application/xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
[/code]

Instructions

  1. From the root of the project run ‘mvn jetty:run’
  2. For the simple example run:
    • xml: http://localhost:8080/CustomProvider/test/simple
    • json: http://localhost:8080/CustomProvider/test/simple.json
    • csv: http://localhost:8080/CustomProvider/test/simple.csv
  3. For the complex example run:
    • xml: http://localhost:8080/CustomProvider/test/complex
    • json: http://localhost:8080/CustomProvider/test/complex.json
    • csv: http://localhost:8080/CustomProvider/test/complex.csv

Screen Shots

When you hit the ‘.csv’ extensions depending on your browser you may notice that the csv is just downloaded as a file.

simple_xml

simple_json

complex_xml

complex_json

CXF Jetty Example

CXF Jetty Example

This is a simple example of how to combine CXF and Jetty to get a simple web services up and running.

Pom for this example:

[code language=”xml”]
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>datadidit.helpful.hints</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>jetty-cxf</artifactId>
<name>jetty-cxf</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
</plugin>
</plugins>
</build>
</project>
[/code]

 

Here is a simple REST endpoint:

[code language=”Java”]
package datadidit.helpful.hints.rest.cxf;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("hello")
public class HelloCXF {
@GET
@Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
public Response sayHello(){
return Response.ok("Hello").build();
}

@GET
@Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Path("{name}")
public Response sayHelloToSomeone(@PathParam("name") @DefaultValue("world") String name){
return Response.ok("Hello "+name).build();
}
}
[/code]

Configuration file(web.xml) necessary for configuring Jetty and CXF:

[code language=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>CXF Jetty Example</display-name>
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
<!– Name of the resource –>
<init-param>
<param-name>jaxrs.serviceClasses</param-name>
<param-value>
datadidit.helpful.hints.rest.cxf.HelloCXF
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
[/code]

With this set up I’m able to run the following steps to see my webservice from the browser:

  1. From root of project run ‘mvn jetty:run’
  2. Navigate to http://localhost:8080/hello and the word ‘Hello’ will  be shown to you from the browser
  3. Next navigate to http://localhost:8080/hello/world and the phrase ‘Hello world’ will be shown to you from the browser.
Where is your favorite NFL teams cap space going…Part2(AFC)

Where is your favorite NFL teams cap space going…Part2(AFC)

Part 2 takes a look at what teams in the AFC are doing with their cap space.

AFC East

AFC North

AFC South

AFC West

AFC East

Biggest thing standing out to me below is Miami is spending a lot of money on their DL, 2 times more than league average and almost 30% of their cap space.

AFCE-PerPosition

Buffalo Bills Miami Dolphins New England Patriots New York Jets NFL
DB 29,479,496 27,616,499 17,018,794 38,402,025 26,240,056
DL 33,279,980 43,671,818 26,648,167 23,376,055 21,559,330
LB 16,794,623 10,078,824 18,192,447 14,642,518 21,687,341
OL 23,881,580 32,341,251 28,246,427 31,934,742 25,224,340
QB 6,056,322 13,124,470 15,120,305 15,107,897 17,635,072
RB 10,860,734 4,127,886 5,546,772 7,035,895 7,603,650
ST 3,648,334 2,021,473 5,900,000 4,296,447 4,598,119
TE 7,461,559 11,253,250 14,119,263 2,457,483 7,136,520
WR 13,762,349 7,990,195 18,808,154 23,807,352 17,016,041
Total 145,224,977 152,225,666 149,600,329 161,060,414 148,700,468

AFCE-CapTotal

team_lg cap
Buffalo Bills 145,224,977.00
Miami Dolphins 152,225,666.00
New England Patriots 149,600,329.00
New York Jets 161,060,414.00
NFL 148,700,467.53

AFC North

AFCN-PerPosition

Baltimore Ravens Cincinnati Bengals Cleveland Browns Pittsburgh Steelers NFL
DB 32,608,731 30,917,521 36,129,121 21,018,906 26,240,056
DL 7,940,348 31,438,474 15,739,186 14,649,537 21,559,330
LB 23,899,629 17,117,432 24,706,482 29,272,432 21,687,341
OL 17,769,960 25,827,523 20,441,486 31,713,791 25,224,340
QB 24,053,334 13,750,413 16,804,891 25,414,805 17,635,072
RB 6,578,244 8,165,445 2,229,419 5,333,109 7,603,650
ST 7,540,000 5,521,667 2,833,000 2,833,000 4,598,119
TE 7,916,918 3,396,211 2,987,732 6,936,562 7,136,520
WR 12,972,115 17,898,407 13,766,584 16,140,272 17,016,041
Total 141,279,279 154,033,093 135,637,901 153,312,414 148,700,468

AFCN-CapTotal

team_lg cap
Baltimore Ravens 141,279,279.00
Cincinnati Bengals 154,033,093.00
Cleveland Browns 135,637,901.00
Pittsburgh Steelers 153,312,414.00
NFL 148,700,467.53

AFC South

AFCS-PerPosition

Houston Texans Indianapolis Colts Jacksonville Jaguars Tennessee Titans NFL
DB 27,192,446 21,622,749 28,048,803 31,983,674 26,240,056
DL 22,806,964 10,970,469 35,629,261 20,257,121 21,559,330
LB 27,071,210 26,746,775 17,325,094 23,470,780 21,687,341
OL 29,927,612 25,770,042 23,051,277 21,491,313 25,224,340
QB 14,412,646 19,906,667 10,414,198 7,565,734 17,635,072
RB 10,585,079 5,811,457 6,899,223 12,402,648 7,603,650
ST 3,355,000 6,750,000 3,500,000 6,235,666 4,598,119
TE 2,310,164 11,855,251 11,413,527 11,355,208 7,136,520
WR 8,709,817 17,229,506 13,006,178 18,252,871 17,016,041
Total 146,370,938 146,662,916 149,287,561 153,015,015 148,700,468

AFCS-CapTotal

team_lg cap
Houston Texans 146,370,938.00
Indianapolis Colts 146,662,916.00
Jacksonville Jaguars 149,287,561.00
Tennessee Titans 153,015,015.00
NFL 148,700,467.53

AFC West

AFCW-PerPosition

Denver Broncos Kansas City Chiefs Oakland Raiders San Diego Chargers NFL
DB 33,253,262 20,927,181 34,799,467 26,196,974 26,240,056
DL 15,847,747 17,431,156 13,215,815 17,830,448 21,559,330
LB 27,946,958 38,406,775 30,579,411 23,274,907 21,687,341
OL 15,654,114 21,758,228 37,579,810 25,404,464 25,224,340
QB 9,261,158 19,131,035 4,631,343 22,280,000 17,635,072
RB 9,412,971 10,055,670 9,640,686 7,144,037 7,603,650
ST 5,175,002 5,057,334 10,187,500 2,437,622 4,598,119
TE 6,886,868 3,948,789 5,235,006 7,944,722 7,136,520
WR 25,047,116 20,132,805 18,191,836 17,032,784 17,016,041
Total 148,485,196 156,848,973 164,060,874 149,545,958 148,700,468

AFCW-CapTotal

team_lg cap
Denver Broncos 148,485,196.00
Kansas City Chiefs 156,848,973.00
Oakland Raiders 164,060,874.00
San Diego Chargers 149,545,958.00
NFL 148,700,467.53
Where is your favorite NFL teams cap space going…Part1(NFC)

Where is your favorite NFL teams cap space going…Part1(NFC)

Was interested in getting a look at how each team is spending their cap by position group. In order to get the data I went to spotrac, which is a great site for interactively managing your teams salary cap. The position groups I split that data into are:

QB: Quarterback

RB: Running back which includes Full backs as well

TE: Tight End

WR: Wide Receiver

OL: Offensive line which includes center, gaurd and tackles

ST: Special Teams which includes punter, long snapper, kicker

DL: Defensive line which includes nose tackles, defensive tacklets and defensive end

LB: Linebacker which includes ILB, OLB

DB Defensive backs which includes CB, S, FS, SS

Below are graphs and tables of each teams cap space by division.

NFC East

NFC North

NFC South

NFC West

Technical Details

NFC East

NFCE-PerPosition

Dallas Cowboys New York Giants Philadelphia Eagles Washington Redskins NFL
DB 32,517,674 24,210,851 22,215,313 20,417,799 26,240,056
DL 10,995,953 33,863,231 14,542,212 21,341,639 21,559,330
LB 19,166,315 16,750,859 25,526,573 21,093,256 21,687,341
OL 21,659,580 19,946,109 36,196,468 28,012,731 25,224,340
QB 21,697,516 24,988,400 24,084,500 21,787,333 17,635,072
RB 9,168,992 10,994,037 13,267,311 1,392,909 7,603,650
ST 5,920,000 3,725,000 3,847,168 2,612,500 4,598,119
TE 11,742,142 1,710,047 5,326,897 8,952,278 7,136,520
WR 20,135,362 12,750,655 9,632,507 25,216,781 17,016,041
Total 153,003,534 148,939,189 154,638,949 150,827,226 148,700,468

 

NFCE-CapTotal

team_lg cap
Dallas Cowboys 153,003,534.00
New York Giants 148,939,189.00
Philadelphia Eagles 154,638,949.00
Washington Redskins 150,827,226.00
NFL 148,700,467.53

 

NFC North

NFCN-PerPosition

Chicago Bears Detroit Lions Green Bay Packers Minnesota Vikings NFL
DB 11,933,993 17,976,563 26,425,315 31,075,280 26,240,056
DL 10,802,270 17,658,801 14,155,762 28,816,518 21,559,330
LB 33,848,070 16,110,645 36,248,769 11,125,803 21,687,341
OL 18,892,048 16,635,996 24,802,901 38,342,094 25,224,340
QB 19,606,667 23,385,434 19,830,908 5,121,379 17,635,072
RB 2,113,756 3,389,020 3,888,337 15,089,750 7,603,650
ST 5,330,327 4,600,164 3,940,000 3,196,048 4,598,119
TE 5,299,257 9,369,926 4,639,959 9,842,136 7,136,520
WR 26,532,299 31,995,217 20,514,889 7,375,500 17,016,041
Total 134,358,687 141,121,766 154,446,840 149,984,508 148,700,468

NFCN-CapTotal

team_lg cap
Chicago Bears 134358687
Detroit Lions 141121766
Green Bay Packers 154446840
Minnesota Vikings 149984508
NFL 148700467.5

NFC South

NFCS-PerPosition

Atlanta Falcons Carolina Panthers New Orleans Saints Tampa Bay Buccaneers NFL
DB 12,996,775 9,366,346 30,666,335 29,760,125 26,240,056
DL 21,786,004 20,013,543 14,311,219 32,639,717 21,559,330
LB 13,193,402 16,946,538 25,871,529 14,394,757 21,687,341
OL 32,510,564 23,545,400 24,026,456 24,820,006 25,224,340
QB 26,786,474 22,310,000 32,022,864 8,792,029 17,635,072
RB 2,372,750 14,064,730 10,031,191 9,625,988 7,603,650
ST 6,743,333 5,475,667 5,220,000 3,086,830 4,598,119
TE 4,975,878 7,689,497 5,671,266 5,549,829 7,136,520
WR 26,015,153 10,490,331 5,920,718 19,669,753 17,016,041
Total 147,380,333 129,902,052 153,741,578 148,339,034 148,700,468

NFCS-CapTotal

team_lg cap
Atlanta Falcons 147,380,333.00
Carolina Panthers 129,902,052.00
New Orleans Saints 153,741,578.00
Tampa Bay Buccaneers 148,339,034.00
NFL 148,700,467.53

NFC West

NFCW-PerPosition

Arizona Cardinals Los Angeles Rams San Francisco 49ers Seattle Seahawks NFL
DB 27,549,850 25,316,530 19,046,652 40,990,742 26,240,056
DL 24,358,032 34,440,531 16,521,411 22,919,173 21,559,330
LB 18,545,398 16,014,777 24,957,641 14,674,279 21,687,341
OL 25,449,085 22,096,357 27,191,734 10,257,720 25,224,340
QB 21,297,712 18,203,311 18,825,554 18,547,000 17,635,072
RB 5,233,268 8,486,987 5,216,786 7,151,703 7,603,650
ST 1,450,500 4,720,995 4,652,550 5,326,667 4,598,119
TE 5,184,876 8,339,327 3,991,964 12,604,853 7,136,520
WR 26,263,175 12,138,843 12,967,161 14,146,617 17,016,041
Total 155,331,896 149,757,658 133,371,453 146,618,754 148,700,468

NFCW-CapTotal

 

team_lg cap
Arizona Cardinals 155,331,896.00
Los Angeles Rams 149,757,658.00
San Francisco 49ers 133,371,453.00
Seattle Seahawks 146,618,754.00
NFL 148,700,467.53

Technical Details

The functions I needed to write to get this done are here:

[code language=”r”]
library(ggplot2)
library(plyr)
library(reshape2)
library(scales)
library(xtable)
options(scipen=10)

getDivisionTable <- function(divisionDf){
teamNames <- as.character(unique(divisionDf["team_lg"])[,1])
positionGroups <- as.character(unique(divisionDf["positionGroup"])[,1])

tableData <- c()
for(position in positionGroups){
#print(position)
positionDf <- divisionDf[divisionDf["positionGroup"] == position,]
for(i in 1:length(teamNames)){
#print(teamNames[i])
teamPositionDf <- positionDf[positionDf["team_lg"] == teamNames[i],]
tableData <- c(tableData, prettyNum(as.numeric(teamPositionDf["capHit"]), big.mark = ","))
}
}

#Add Total To table
for(a in 1:length(teamNames)){
teamOnly <- divisionDf[divisionDf["team_lg"] == teamNames[a],]
tableData <- c(tableData, prettyNum(sum(teamOnly["capHit"]), big.mark = ","))
}

table <- matrix(tableData, ncol=length(teamNames), byrow=TRUE)
colnames(table) <- teamNames
rownames(table) <- c(positionGroups, "Total")

return(table)
}

#Class to return
setClass(Class="CapDfs",representation(
divisionCapPerPositionGroup="data.frame",
divisionCapTotalPerTeam="data.frame",
divisonTable="matrix",
division="character"
))

#Get graph’s and tables by division
generateCapOutputPerDivision <- function(allDf, division){
#Strip out each entry with a percentage and get rid of any entry left over
#that doesn’t have a cap hit
all_hitCap <- all_tm_caps[!is.na(allDf$percentage),]
all_hitCap <- all_hitCap[!is.na(all_hitCap$capHit),]

#Summarise data by teamName, division, positionGroup
all_tms_pos_group <- ddply(all_hitCap, .(teamName,division,positionGroup), summarise, capNum=sum(capHit))

#Add an NFL Constant to help summarise league averages
league <- rep("NFL", nrow(all_tms_pos_group))

#Bind the league constant
all_tms_pos_group <- cbind(all_tms_pos_group, league)

#Summarize all the data by league
league_summary <- ddply(all_tms_pos_group, .(league,positionGroup), summarise, cap=mean(capNum))

#Filter by division
divisionDf <- all_tms_pos_group[all_tms_pos_group$division == division,]

#Add League summary back in here:
divisionDf <- subset(divisionDf, select = -c(division, league))
colnames(divisionDf) <- c("team_lg", "positionGroup", "capHit")
colnames(league_summary) <- c("team_lg", "positionGroup", "capHit")

#Combine date
divisionDf <- rbind(divisionDf, league_summary)

#Total by division
totalDf <- ddply(divisionDf, .(team_lg), summarise, cap=sum(capHit))

divisionTable <- getDivisionTable(divisionDf)
#divisionTable <- xtable(divisionTable)

#Put data in class
return(new("CapDfs",divisionCapPerPositionGroup=divisionDf,
divisionCapTotalPerTeam=totalDf,
divisonTable=divisionTable,
division=division))
}
[/code]

With those functions in place I was able to create the necessary graphs and tables with the following code:

[code language=”r”]
#Read in data
all_tm_caps <- getDfFromDir("data/")

#Create filter
dataFilter <- c("NFCE", "NFCN", "NFCS", "NFCW", "AFCE", "AFCN", "AFCS", "AFCW")

for(division in dataFilter){
print(paste("Division", division))
divisionData <- generateCapOutputPerDivision(all_tm_caps, division)

#Graph Division Data
ggplot(data=divisionData@divisionCapPerPositionGroup, aes(x=team_lg, capHit, fill=positionGroup )) + geom_bar(stat="identity", position="dodge") + ggtitle(paste(divisionData@division, "Cap Per Team")) + theme(axis.text.x = element_text(angle = 45, hjust = 1))

#Write PNG
ggsave(filename=paste(division, "PerPosition.png", sep="-"))

#Position Group
write.csv(divisionData@divisonTable, paste(division, "TablePerPositionGroup.csv"))

#Write CSV
ggplot(data=divisionData@divisionCapTotalPerTeam, aes(x=team_lg, cap)) + geom_bar(stat="identity") + ggtitle(paste(divisionData@division, " Total Cap Per Team"))

#Write PNG
ggsave(filename=paste(division, "CapTotal.png", sep="-"))

#Total
write.csv(divisionData@divisionCapTotalPerTeam, paste(division, "TableTotal.csv"))
}
[/code]