This post is very generic cruft on basic data analysis designed around combining data with :
- cbind()
- rbind()
- matrix()
- as.matrix()
- data.frame()
- as.data.frame()
and visualizing data with the lattice graphics package.
Some quick and dirty notes on learning R. I have found virtual libraries exist both on and offline for learning R. However, I have also found that R is a peculiar and specific language. I would compare the semantics most to SQL, but somehow that comparison stops being useful quickly. Ironically, given the power of R language quantitative analysis, I have found the user really wants to get the "feel of R" inside his forearms to become useful and self-confident. Spending time manipulating and re-organizing data is essential at each step of your curriculum in learning R. Functionally, R is a mathematical platform and benefits from domain specific packages and knowledge. But the R language is also a unique engine type with programmable limits. R does certain functionality very well. Other functionality perhaps more typical of many programming languages is simply outside the subset of R. There is art to successful use of R. There is an important 'R' mentality that only serious practice will enjoin.
This post follows from my last post on combining data for analysis. I am using BEA, BLS, and Census data to understand 20 year macro-economic flows. Some examples on how to use cbind, rbind, matrix, as.data.frame commands to re-organize this data are here. Below are some functions I have created to help explicate the data set ('dd'). They are slightly more concise/useful than the function 'str(dd)'. The user will recall that I have concatenated data from mulitple sets into one dataframe. I have used prefixes (BLS,PI,NS) designate "Bureau of Labor Statistics", (BEA) Personal Income, (BEA) Net (residential) Stock.
getdf <- function(x) {as.data.frame(cbind(Class=sapply(x,class)),optional=TRUE)}
dfclass <- function(x,y) {as.matrix(grep(pattern=x,(as.character(names(y))),value=TRUE))}
print_matrix <- function(x) {
matrix1 <- matrix(sapply(x,class))
matrix1 <- cbind(matrix1,matrix(names(x)))
print(matrix1)
}Class
Year integer
BLS.Employment integer
BLS.CivLabForce integer
BLS.Census.Population integer
BLS.EmployPopRatio numeric
BLS.Census.EMP_CLF numeric
BLS.Census.EMP_POP numeric
BLS.Census.CLF_POP numeric
PI.PersonalInc numeric
PI.EmployeeComp numeric
PI.ProprietorInc numeric
PI.RentalInc numeric
PI.AssetReceipts numeric
PI.InterestInc numeric
PI.DividendInc numeric
PI.TransferReceipts numeric
PI.GovBenefits numeric
PI.OtherTransfer numeric
NS.ResidentialFixedAssets numeric
NS.Private numeric
NS.Corporate numeric
NS.Noncorp numeric
NS.Sole_prop_partner numeric
NS.Nonprofit numeric
NS.Households numeric
NS.Government numeric
NS.Federal numeric
NS.StateLocal numeric
NS.OwnerOccupied numeric
NS.TenantOccupied numeric
> dfclass("PI",dd)
[,1]
[1,] "PI.PersonalInc"
[2,] "PI.EmployeeComp"
[3,] "PI.ProprietorInc"
[4,] "PI.RentalInc"
[5,] "PI.AssetReceipts"
[6,] "PI.InterestInc"
[7,] "PI.DividendInc"
[8,] "PI.TransferReceipts"
[9,] "PI.GovBenefits"
[10,] "PI.OtherTransfer"
> print_matrix(dd)
[,1] [,2]
[1,] "integer" "Year"
[2,] "integer" "BLS.Employment"
[3,] "integer" "BLS.CivLabForce"
[4,] "integer" "BLS.Census.Population"
[5,] "numeric" "BLS.EmployPopRatio"
[6,] "numeric" "BLS.Census.EMP_CLF"
[7,] "numeric" "BLS.Census.EMP_POP"
[8,] "numeric" "BLS.Census.CLF_POP"
[9,] "numeric" "PI.PersonalInc"
[10,] "numeric" "PI.EmployeeComp"
[11,] "numeric" "PI.ProprietorInc"
[12,] "numeric" "PI.RentalInc"
...
Str() also works well to enumerate a dataframe:
> str(dd)
'data.frame': 20 obs. of 30 variables:
$ Year : int 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 ...
$ BLS.Employment : int 118492 120259 123060 124900 126708 129558 131463 133488 136891 136933 ...
$ BLS.CivLabForce : int 128105 129200 131056 132304 133943 136297 137673 139368 142583 143734 ...
$ BLS.Census.Population : int 256894 260255 263436 266557 269667 272912 276115 279295 282385 285309 ...
$ BLS.EmployPopRatio : num 0.615 0.617 0.625 0.629 0.632 0.638 0.641 0.643 0.644 0.637 ...
$ BLS.Census.EMP_CLF : num 0.925 0.931 0.939 0.944 0.946 0.951 0.955 0.958 0.96 0.953 ...
$ BLS.Census.EMP_POP : num 0.925 0.931 0.939 0.944 0.946 0.951 0.955 0.958 0.96 0.953 ...
$ BLS.Census.CLF_POP : num 0.499 0.496 0.497 0.496 0.497 0.499 0.499 0.499 0.505 0.504 ...
$ PI.PersonalInc : num 5347 5568 5875 6201 6592 ...
$ PI.EmployeeComp : num 3647 3791 3981 4179 4388 ...
$ PI.ProprietorInc : num 415 450 485 516 584 ...
$ PI.RentalInc : num 84.6 114.1 142.9 154.6 170.4 ...
$ PI.AssetReceipts : num 910 900 948 1005 1081 ...
$ PI.InterestInc : num 722 698 713 752 784 ...
$ PI.DividendInc : num 188 202 235 253 296 ...
$ PI.TransferReceipts : num 746 791 826 879 924 ...
$ PI.GovBenefits : num 730 777 813 860 901 ...
$ PI.OtherTransfer : num 16.3 14.1 13.3 18.7 22.9 19.4 26 34 42.4 46.8 ...
$ NS.ResidentialFixedAssets: num 6744 7160 7668 8009 8449 ...
$ NS.Private : num 6586 6990 7486 7821 8253 ...
$ NS.Corporate : num 69.6 71.5 74.6 77.4 81.1 ...
$ NS.Noncorp : num 6516 6918 7411 7743 8172 ...
$ NS.Sole_prop_partner : num 617 634 656 681 714 ...
$ NS.Nonprofit : num 110 112 116 117 120 ...
$ NS.Households : num 5788 6172 6639 6945 7337 ...
$ NS.Government : num 159 170 182 188 196 ...
$ NS.Federal : num 52.7 56.4 59.9 61.6 63.8 66 68.7 72.2 75.3 79.1 ...
$ NS.StateLocal : num 106 114 122 126 133 ...
$ NS.OwnerOccupied : num 4918 5267 5694 5975 6333 ...
$ NS.TenantOccupied : num 1801 1866 1945 2005 2087 ...
Once we have peeked at our data, we can start using graphics packages like lattice to visualize data. I find that visualizing is a critical step in understanding the relationships of data; the specifics of which are not always immediately clear. The lattice graphic package (which ships with the standard installation) lets us rather easily add multiple multiple data sets across the same Y axis (e.g. "Year") through concatenation. Also added are a specific Y label, key, line type (ylab,auto.key,type). I use the lattice package "xyplot" function. All measurements are in billions:
xyplot(NS.Households + PI.PersonalInc + PI.GovBenefits ~ Year,ylab="Non Specific",auto.key=TRUE,type="b")
What we perceive at first glance wouldn't surprise many observers of the American economy for the last twenty years. Nominally, we have seen increasing valuation of housing stock and personal income, and government benefits. 2008 - 2009 brought a "crash" to the housing stock valuation and personal income and a simultaneous increase in government spending. However, even this non specific chart shows the "bubble" in housing stock valuation whose "bursting" resulted in precipitous decline in personal income. Now let us try something a bit more complex. Below, I scale and create data sets to help me visually understand and weight macro-economic change. Notice that inside parentheses the operands "+" or "-" perform math; otherwise they concatenate X axis data.
xyplot(BLS.Census.Population/100 + PI.GovBenefits + (BLS.Census.CLF_POP * 5000) + (NS.Households - PI.PersonalInc) ~ Year,ylab="Divergence",auto.key=TRUE,type="b")
The orange line represents the increasing difference between household value and personal income we saw in the first chart. Only this time, we can readily see that difference crest at about $5 Trillion in 2007 before taking a dive. Total population is originally measured in millions, so I divide it by 100 to smack it front and center in this graph of billions. BLS statistics give us the employed labor force divided by the potential working force as a percentage. (This is not the vaunted unemployment measures U-3 or U-6!) I multiply this percentage by 5000 so the relationship between total population and a shrinking work force percentage (over time) is made clear. Government benefits fit into this graph without scaling. Clearly, they have been rising nominally well before Barack Obama took office and government stimulus packages were deployed.
From this graph we could deduce more sharply the American economic dilemma: a disjointed housing bubble, a shrinking workforce percentage (e.g. an aging population), a steadily increasing population and an economy dependent upon increasing government benefits. Let us try another approach at visualizing similar data, but before we do some comments on employment and population percentages may be useful. The total amount of employed persons in the United States is always some percentage of the civil labor force which in turn is always some percentage of the total population. These numbers are always much different than U-3 or U-6 which are the usual measures of unemployment. Let us take a look at this data for the last year in my data set from the BLS and Census. To do this, I am going to bind three columns as matrices from my dataframe. This code formats indexed dataframe information nicely:
> cbind(matrix(names(ddBLS)),matrix(ddBLS[1,1:8]), matrix(ddBLS[20,1:8]))
[,1] [,2] [,3]
[1,] "Year" 1992 2011
[2,] "BLS.Employment" 118492 139869
[3,] "BLS.CivLabForce" 128105 153617
[4,] "BLS.Census.Population" 256894 312603
[5,] "BLS.EmployPopRatio" 0.615 0.584
[6,] "BLS.Census.EMP_CLF" 0.925 0.911
[7,] "BLS.Census.EMP_POP" 0.461 0.447
[8,] "BLS.Census.CLF_POP" 0.499 0.491
xyplot(BLS.Census.EMP_CLF + BLS.EmployPopRatio + BLS.Census.CLF_POP + BLS.Census.EMP_POP ~ Year,type="b",ylab="BLS Employment %",auto.key=TRUE)
par(mfrow=c(2,2), pch=16)
attach(USEmployPop.1992.2011)
plot(Year,BLS.Employment,type="b")
plot(Year,BLS.CivLabForce,type="b")
plot(Year,BLS.Census.CLF_POP, type="b")
plot(Year,BLS.Census.EMP_POP,type="b")
detach(USEmployPop.1992.2011)
par(mfrow=c(1,1), pch=1)
diff1 <- as.data.frame(cbind(Year,'BLS.Total.Employment(M)'=BLS.Employment/100,NS.ResidentialFixedAssets,PI.PersonalInc,'Diff(NS.RFA - PI.PInc)' = (NS.ResidentialFixedAssets - PI.PersonalInc)))
diff1
No comments:
Post a Comment