This script will analyze the two different data tables we filled in earlier with LMT or licensed massage therapist state licensing requirements, median home values according to Zillow, 2018 median and race demographics per state according to data.census.gov, two bedroom and two bath rental apartments average price per state using one of either the three most populated cities or the ten most populated cities according to apartments.com, the number of businesses for one of nine types of businesses, and the average hourly, salary, and number of jobs for one of 20 specific jobs in one of either the top 3 or 10 populated cities as a mean or average value for each state according to Indeed.com. There are two tables where one uses the mean of the three top populated cities and the other data table uses the mean of the top ten populated cities. I have put those data files as csv file into this same folder to read into Rstudio and analyze. The data was obtained between July 7, 2020 and July 22, 2020, but the 3 cities on July 15-17 and the 10 cities on July 20-22 of 2020.
It should be noted, that even though the business was listed on yellowpages.com, the notation ‘Closed’ or ‘Temporarily Closed’ wasn’t figured into these aggregate values. The orignal tables are still accessible but this would be a different project of counting those before, during, and after quarantine that are closed or temporarily, if I get that other information. I only have some of it for the 2nd round of closures in my location around mid July 2020, and not before, during, or after the 1st quarantine closure in Mar-Jun 2020. It is time consuming to grab all the data, and who knows how much longer they will allow access to their web page for get requests. Rent.com is one such site, and I am sure yelp.com is also where the data isn’t available to extract as text html and parse with programs such as rvest in R.
There aren’t that many significant number of businesses that closed when searching within the state for certain types of businesses like chiropractors or wellness centers. So, any change might be negligible to adding information to how an LMT would fair in the various job markets and living costs of each state based on the three and ten most populated city data from each state.
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
library(ggplot2)
library(grid)
library(gridExtra)
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
The 10 city data:
tenCities <- read.csv('stateLicensingDemographicsAddedAndUpdated - 10cityJuly222020.csv', sep=',', header=T, na.strings=c('',' ','NA'), stringsAsFactors = F)
The three city data:
threeCities <- read.csv('stateLicensingDemographicsAddedAndUpdated - 3cityJuly172020.csv', sep=',',header=T, na.strings=c('',' ','NA'),stringsAsFactors = F)
TenCities columns:
colnames(tenCities)
## [1] "stateAbbreviation"
## [2] "state"
## [3] "massageBoard"
## [4] "licenseByReciprocity"
## [5] "proofOtherOrAllStateLicense"
## [6] "stateResidencyProof"
## [7] "passportSizePhoto"
## [8] "driversLicensePhotoCopy"
## [9] "nameChangeProof"
## [10] "socialSecurityCopy"
## [11] "Hours"
## [12] "MBLEX_or_NCBTMB"
## [13] "goodHealthClearance"
## [14] "BoardBackgroundCheckFee"
## [15] "stateApplyingBackgroundCheck"
## [16] "DOJ_backgroundCheck"
## [17] "applicationCost"
## [18] "licensingCost"
## [19] "licenseRenewalFee"
## [20] "CPR_certification"
## [21] "licensingETA"
## [22] "healthReferences"
## [23] "CEU"
## [24] "timeLicenseValidYears"
## [25] "liabilityInsurance"
## [26] "schoolTranscripts"
## [27] "MBLEX_transcript"
## [28] "notes"
## [29] "notes2"
## [30] "notes3"
## [31] "notes4"
## [32] "citiesGreaterThan300k_orTop3"
## [33] "LMT_AvgJobsListed_IndeedFirst5pages"
## [34] "LMT_HourlyAvgPayRangeAdvertised_Indeed"
## [35] "LMT_AnualAvgPayAdvertised_Indeed"
## [36] "Zillow_2BR_10cityAverageHomeValue"
## [37] "median2018IncomeByState"
## [38] "total_state_population"
## [39] "percent_black"
## [40] "percent_white"
## [41] "percent_two_or_more"
## [42] "percent_Native_American"
## [43] "percent_Asian"
## [44] "percent_Pacific_Islander"
## [45] "percent_Latino"
## [46] "cashier_jobsListed"
## [47] "cashier_avgHourly"
## [48] "cashier_avgAnnualSalary"
## [49] "server_jobsListed"
## [50] "server_avgHourly"
## [51] "server_avgAnnualSalary"
## [52] "personalTrainer_jobsListed"
## [53] "personalTrainer_avgHourly"
## [54] "personalTrainer_avgAnnualSalary"
## [55] "houseCleaner_jobsListed"
## [56] "houseCleaner_avgHourly"
## [57] "houseCleaner_avgAnnualSalary"
## [58] "warehouse_jobsListed"
## [59] "warehouse_avgHourly"
## [60] "warehouse_avgAnnualSalary"
## [61] "security_jobsListed"
## [62] "security_avgHourly"
## [63] "security_avgAnnualSalary"
## [64] "nanny_jobsListed"
## [65] "nanny_avgHourly"
## [66] "nanny_avgAnnualSalary"
## [67] "clerical_jobsListed"
## [68] "clerical_avgHourly"
## [69] "clerical_avgAnnualSalary"
## [70] "tutor_jobsListed"
## [71] "tutor_avgHourly"
## [72] "tutor_avgAnnualSalary"
## [73] "teacher_jobsListed"
## [74] "teacher_avgHourly"
## [75] "teacher_avgAnualSalary"
## [76] "dataScientist_jobsListed"
## [77] "dataScientist_avgHourly"
## [78] "dataScientist_avgAnualSalary"
## [79] "nurses.jobsListed"
## [80] "nurses.avgHourly"
## [81] "nurses.avgAnualSalary"
## [82] "personalAssistant.jobsListed"
## [83] "personalAssistant.avgHourly"
## [84] "personalAssistant.avgAnualSalary"
## [85] "chiropractor.jobsListed"
## [86] "chiropractor.avgHourly"
## [87] "chiropractor.avgAnualSalary"
## [88] "physicalTherapist.jobsListed"
## [89] "physicalTherapist.avgHourly"
## [90] "physicalTherapist.avgAnualSalary"
## [91] "esthetician.jobsListed"
## [92] "esthetician.avgHourly"
## [93] "esthetician.avgAnualSalary"
## [94] "medicalSpaEsthetician.jobsListed"
## [95] "medicalSpaEsthetician.avgHourly"
## [96] "medicalSpaEsthetician.avgAnualSalary"
## [97] "medicalDoctor.jobsListed"
## [98] "medicalDoctor.avgHourly"
## [99] "medicalDoctor.avgAnualSalary"
## [100] "yogaInstructor.jobsListed"
## [101] "yogaInstructor.avgHourly"
## [102] "yogaInstructor.avgAnualSalary"
## [103] "pilatesInstructor.jobsListed"
## [104] "pilatesInstructor.avgHourly"
## [105] "pilatesInstructor.avgAnualSalary"
## [106] "chiropractor_businessListings"
## [107] "wellness.clinic_businessListings"
## [108] "massage.spa_businessListings"
## [109] "yoga_businessListings"
## [110] "gym_businessListings"
## [111] "coffee_businessListings"
## [112] "health.food_businessListings"
## [113] "hair.salon_businessListings"
## [114] "tanning_businessListings"
## [115] "TwoBedroomApartment_Listings._10cities"
## [116] "Rent2BR2BA_MinPrice._10cities"
## [117] "Rent2BR2BA_MaxPrice._10cities"
## [118] "Rent2BR2BA_AvgPrice._10cities"
First few rows of tenCities data:
head(tenCities)
ThreeCities columns:
colnames(threeCities)
## [1] "stateAbbreviation"
## [2] "state"
## [3] "massageBoard"
## [4] "licenseByReciprocity"
## [5] "proofOtherOrAllStateLicense"
## [6] "stateResidencyProof"
## [7] "passportSizePhoto"
## [8] "driversLicensePhotoCopy"
## [9] "nameChangeProof"
## [10] "socialSecurityCopy"
## [11] "Hours"
## [12] "MBLEX_or_NCBTMB"
## [13] "goodHealthClearance"
## [14] "BoardBackgroundCheckFee"
## [15] "stateApplyingBackgroundCheck"
## [16] "DOJ_backgroundCheck"
## [17] "applicationCost"
## [18] "licensingCost"
## [19] "licenseRenewalFee"
## [20] "CPR_certification"
## [21] "licensingETA"
## [22] "healthReferences"
## [23] "CEU"
## [24] "timeLicenseValidYears"
## [25] "liabilityInsurance"
## [26] "schoolTranscripts"
## [27] "MBLEX_transcript"
## [28] "notes"
## [29] "notes2"
## [30] "notes3"
## [31] "notes4"
## [32] "citiesGreaterThan300k_orTop3"
## [33] "LMT_AvgJobsListed_IndeedFirst5pages"
## [34] "LMT_HourlyAvgPayRangeAdvertised_Indeed"
## [35] "LMT_AnualAvgPayAdvertised_Indeed"
## [36] "Zillow_2BR_3cityAverageHomeValue"
## [37] "median2018IncomeByState"
## [38] "total_state_population"
## [39] "percent_black"
## [40] "percent_white"
## [41] "percent_two_or_more"
## [42] "percent_Native_American"
## [43] "percent_Asian"
## [44] "percent_Pacific_Islander"
## [45] "percent_Latino"
## [46] "cashier_jobsListed"
## [47] "cashier_avgHourly"
## [48] "cashier_avgAnnualSalary"
## [49] "server_jobsListed"
## [50] "server_avgHourly"
## [51] "server_avgAnnualSalary"
## [52] "personalTrainer_jobsListed"
## [53] "personalTrainer_avgHourly"
## [54] "personalTrainer_avgAnnualSalary"
## [55] "houseCleaner_jobsListed"
## [56] "houseCleaner_avgHourly"
## [57] "houseCleaner_avgAnnualSalary"
## [58] "warehouse_jobsListed"
## [59] "warehouse_avgHourly"
## [60] "warehouse_avgAnnualSalary"
## [61] "security_jobsListed"
## [62] "security_avgHourly"
## [63] "security_avgAnnualSalary"
## [64] "nanny_jobsListed"
## [65] "nanny_avgHourly"
## [66] "nanny_avgAnnualSalary"
## [67] "clerical_jobsListed"
## [68] "clerical_avgHourly"
## [69] "clerical_avgAnnualSalary"
## [70] "tutor_jobsListed"
## [71] "tutor_avgHourly"
## [72] "tutor_avgAnnualSalary"
## [73] "teacher_jobsListed"
## [74] "teacher_avgHourly"
## [75] "teacher_avgAnualSalary"
## [76] "dataScientist_jobsListed"
## [77] "dataScientist_avgHourly"
## [78] "dataScientist_avgAnualSalary"
## [79] "nurses.jobsListed"
## [80] "nurses.avgHourly"
## [81] "nurses.avgAnualSalary"
## [82] "personalAssistant.jobsListed"
## [83] "personalAssistant.avgHourly"
## [84] "personalAssistant.avgAnualSalary"
## [85] "chiropractor.jobsListed"
## [86] "chiropractor.avgHourly"
## [87] "chiropractor.avgAnualSalary"
## [88] "physicalTherapist.jobsListed"
## [89] "physicalTherapist.avgHourly"
## [90] "physicalTherapist.avgAnualSalary"
## [91] "esthetician.jobsListed"
## [92] "esthetician.avgHourly"
## [93] "esthetician.avgAnualSalary"
## [94] "medicalSpaEsthetician.jobsListed"
## [95] "medicalSpaEsthetician.avgHourly"
## [96] "medicalSpaEsthetician.avgAnualSalary"
## [97] "medicalDoctor.jobsListed"
## [98] "medicalDoctor.avgHourly"
## [99] "medicalDoctor.avgAnualSalary"
## [100] "yogaInstructor.jobsListed"
## [101] "yogaInstructor.avgHourly"
## [102] "yogaInstructor.avgAnualSalary"
## [103] "pilatesInstructor.jobsListed"
## [104] "pilatesInstructor.avgHourly"
## [105] "pilatesInstructor.avgAnualSalary"
## [106] "chiropractor_businessListings"
## [107] "wellness.clinic_businessListings"
## [108] "massage_businessListings"
## [109] "yoga_businessListings"
## [110] "gym_businessListings"
## [111] "coffee_businessListings"
## [112] "health.food_businessListings"
## [113] "hair.salon_businessListings"
## [114] "tanning_businessListings"
## [115] "TwoBedroomApartment_Listings"
## [116] "Rent2BR2BA_MinPrice"
## [117] "Rent2BR2BA_MaxPrice"
## [118] "Rent2BR2BA_AvgPrice"
First few rows of threeCities data:
head(threeCities)
We can see which columns are not identical in name:
diffNames <- colnames(tenCities)==colnames(threeCities)
diffNames
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [13] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [25] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## [37] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [49] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [61] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [73] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [85] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [97] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## [109] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
colnames(tenCities)[diffNames==FALSE]
## [1] "Zillow_2BR_10cityAverageHomeValue"
## [2] "massage.spa_businessListings"
## [3] "TwoBedroomApartment_Listings._10cities"
## [4] "Rent2BR2BA_MinPrice._10cities"
## [5] "Rent2BR2BA_MaxPrice._10cities"
## [6] "Rent2BR2BA_AvgPrice._10cities"
The above shows the colnames of tenCities that are different in location names of threeCities. This was done to make sure when comparing that anybody who viewed the ten city table would know the data is different for that reason. The massage.spa_businessListings is different but just as a naming error when building the table or filling it in from its origation script.
All the massage state licensing columns are the columns 1-31, and are the same data as they were extensions of updates and additional columns from the same original csv file on state licensing. Lets get all that information into a separate table of just state licensing.
stateLicensing <- tenCities[,c(1:31)]
colnames(stateLicensing)
## [1] "stateAbbreviation" "state"
## [3] "massageBoard" "licenseByReciprocity"
## [5] "proofOtherOrAllStateLicense" "stateResidencyProof"
## [7] "passportSizePhoto" "driversLicensePhotoCopy"
## [9] "nameChangeProof" "socialSecurityCopy"
## [11] "Hours" "MBLEX_or_NCBTMB"
## [13] "goodHealthClearance" "BoardBackgroundCheckFee"
## [15] "stateApplyingBackgroundCheck" "DOJ_backgroundCheck"
## [17] "applicationCost" "licensingCost"
## [19] "licenseRenewalFee" "CPR_certification"
## [21] "licensingETA" "healthReferences"
## [23] "CEU" "timeLicenseValidYears"
## [25] "liabilityInsurance" "schoolTranscripts"
## [27] "MBLEX_transcript" "notes"
## [29] "notes2" "notes3"
## [31] "notes4"
I want the hours separated out, and all additional information after the number of hours of education required by state for massage therapy licensing is split from its numeric to character information by a semicolon, ‘;’.
hoursString <- strsplit(stateLicensing$Hours,split=';')
hours <- lapply(hoursString,'[',1)
hours1 <- as.integer(hours)
hours1
## [1] 650 500 700 500 500 500 750 500 500 500 570 500 600 625 600
## [16] 500 600 500 500 600 550 500 NA 700 500 500 1000 550 750 500
## [31] 650 1000 500 750 750 500 625 600 500 500 500 500 500 600 NA
## [46] 500 500 500 600 NA
stateLicensing$EdReqHours <- hours1
stateLicensing <- stateLicensing[,c(1:10,32,11:31)]
stateLicensing[,c(1,11:12)]
There are some states that will allow licensing by endorsement if the LMT has been licensed in another state for a certain amount of time. Lets pull out those states.
endorsed <- stateLicensing[!is.na(stateLicensing$licenseByReciprocity),]
Tennessee doesn’t allow license by reciprocity, and they are in the list, because they were the only entry with ‘No’ in this column. We will remove it now.
endorsed <- subset(endorsed, endorsed$licenseByReciprocity != 'No')
There are 26 states that allow licensing by endorsement, but some states still make applicants fill out all other education requirements, or have to verify education requirements like North Carolina and South Carolina. Or some also require the LMT be licensed in another state at least five years as Ohio does or only six months like Arizona. There are many variations on state licensing endorsements, just like within the distribution of hours required in massage education for licensing. Those 26 states allowing endorsement are:
endorsed$stateAbbreviation
## [1] "AZ" "CO" "CT" "ID" "IL" "LA" "MS" "MT" "NE" "NJ" "NM" "NC" "ND" "OH" "OK"
## [16] "OR" "PA" "RI" "SC" "SD" "TX" "UT" "VA" "WA" "WV" "WI"
Lets make a table of those states that don’t have a state massage board set up. They are marked NA in the Hours column. This doesn’t mean each county or district doesn’t have licensing regulations for massage, but that the state hasn’t taken over to make every licensed massage therapist go through the same consistent or transparent steps to work as a massage therapist anywhere in the state.
nonRegulated <- stateLicensing[is.na(stateLicensing$Hours),]
Lets look at those states that don’t have a state massage therapy board for licensing and regulating massage therapists across their state.
nonRegulated$stateAbbreviation
## [1] "MN" "VT" "WY"
Now, lets get a separate list of those states that require more than 500 hours and those that require 500 hours or less.
hours500 <- subset(stateLicensing, stateLicensing$EdReqHours <= 500)
hours500plus <- subset(stateLicensing, stateLicensing$EdReqHours > 500)
Those states requiring less than or equal to 500 hours of massage education or with no requirements are:
hours500$stateAbbreviation
## [1] "AK" "AR" "CA" "CO" "DE" "FL" "GA" "ID" "KS" "LA" "ME" "MI" "MO" "MT" "NJ"
## [16] "NC" "OK" "RI" "SC" "SD" "TN" "TX" "VA" "WA" "WV"
length(hours500$stateAbbreviation)
## [1] 25
Those states requiring more than 500 hours of massage education are:
hours500plus$stateAbbreviation
## [1] "AL" "AZ" "CT" "HI" "IL" "IN" "IA" "KY" "MD" "MA" "MS" "NE" "NV" "NH" "NM"
## [16] "NY" "ND" "OH" "OR" "PA" "UT" "WI"
length(hours500plus$stateAbbreviation)
## [1] 22
There are 22 states that require more than 22 hours of massage education and 25 states that require less than or up to 500 hours minimum and 3 that have no requirements.
How many of those states that require more than 500 hours of education are states that accept licensing by endorsement?
endorsed500plus <- hours500plus$stateAbbreviation %in% endorsed$stateAbbreviation
endorsed_500plus <- hours500plus[endorsed500plus,]
Lets make these subsets of data into lists and create the larger tables from the main data tables for the 10 and 3 city average state data (most populated cities).
We have our endorsed states, the states with 500/less than 500/NA hours, the states with more than 500 hours, and the states with more than 500 hours but allow endorsements.
Lists:
endorsedList <- endorsed$stateAbbreviation
endorsedAnd500PlusList <- endorsed_500plus$stateAbbreviation
lessEqual500List <- hours500$stateAbbreviation
moreThan500List <- hours500plus$stateAbbreviation
Lets see those lists:
endorsedList
## [1] "AZ" "CO" "CT" "ID" "IL" "LA" "MS" "MT" "NE" "NJ" "NM" "NC" "ND" "OH" "OK"
## [16] "OR" "PA" "RI" "SC" "SD" "TX" "UT" "VA" "WA" "WV" "WI"
endorsedAnd500PlusList
## [1] "AZ" "CT" "IL" "MS" "NE" "NM" "ND" "OH" "OR" "PA" "UT" "WI"
lessEqual500List
## [1] "AK" "AR" "CA" "CO" "DE" "FL" "GA" "ID" "KS" "LA" "ME" "MI" "MO" "MT" "NJ"
## [16] "NC" "OK" "RI" "SC" "SD" "TN" "TX" "VA" "WA" "WV"
moreThan500List
## [1] "AL" "AZ" "CT" "HI" "IL" "IN" "IA" "KY" "MD" "MA" "MS" "NE" "NV" "NH" "NM"
## [16] "NY" "ND" "OH" "OR" "PA" "UT" "WI"
Lets also make a list of those states separately that aren’t regulated.
nonRegulatedList <- nonRegulated$stateAbbreviation
nonRegulatedList
## [1] "MN" "VT" "WY"
Since there are only three states in the nonRegulated LMT state licensing data, lets look at the number of jobs available for LMTs in these states in the 10 and 3 most populated cities, respectively.
nonReg10 <- filter(tenCities,tenCities$stateAbbreviation %in% nonRegulatedList)
nr10_jobsAvail <- nonReg10[,c(1,33:45,106:118)]
nr10_jobsAvail
## stateAbbreviation LMT_AvgJobsListed_IndeedFirst5pages
## 1 MN 604
## 2 VT 160
## 3 WY 55
## LMT_HourlyAvgPayRangeAdvertised_Indeed LMT_AnualAvgPayAdvertised_Indeed
## 1 34.00250 76209.6
## 2 28.48387 40000.0
## 3 25.00000 NA
## Zillow_2BR_10cityAverageHomeValue median2018IncomeByState
## 1 252568.0 70315
## 2 193815.5 60782
## 3 240742.7 61584
## total_state_population percent_black percent_white percent_two_or_more
## 1 5611179 6.6 82.5 3.1
## 2 626299 1.2 94.1 2.0
## 3 577737 0.6 91.5 2.4
## percent_Native_American percent_Asian percent_Pacific_Islander percent_Latino
## 1 1.1 4.9 0.0 5.5
## 2 0.3 1.9 0.0 2.0
## 3 2.8 1.0 0.2 10.0
## chiropractor_businessListings wellness.clinic_businessListings
## 1 1542 1262
## 2 714 245
## 3 260 177
## massage.spa_businessListings yoga_businessListings gym_businessListings
## 1 1415 1257 1302
## 2 851 448 520
## 3 317 184 138
## coffee_businessListings health.food_businessListings
## 1 1343 1328
## 2 589 575
## 3 188 193
## hair.salon_businessListings tanning_businessListings
## 1 2286 1165
## 2 1070 110
## 3 562 68
## TwoBedroomApartment_Listings._10cities Rent2BR2BA_MinPrice._10cities
## 1 233 1919.225
## 2 28 1699.231
## 3 30 846.360
## Rent2BR2BA_MaxPrice._10cities Rent2BR2BA_AvgPrice._10cities
## 1 2928.744 2347.035
## 2 1768.750 1709.077
## 3 1013.000 875.080
Since in the above the annual average salary is NA but the average hourly is available, lets make the average annual salary that of a massage therapist, 25 hours per week at the hourly rate for 52 weeks in a year. Because we want to plot this to look at visually.
nr10_jobsAvail$LMT_AnualAvgPayAdvertised_Indeed <- ifelse(is.na(nr10_jobsAvail$LMT_AnualAvgPayAdvertised_Indeed),
nr10_jobsAvail$LMT_HourlyAvgPayRangeAdvertised_Indeed*25*52,
nr10_jobsAvail$LMT_AnualAvgPayAdvertised_Indeed)
Now, lets see the annual pay for LMT in one of these non-regulated states based on Indeed’s advertised data on pay that employers were willing to pay recruited LMTs.
nr10_jobsAvail
## stateAbbreviation LMT_AvgJobsListed_IndeedFirst5pages
## 1 MN 604
## 2 VT 160
## 3 WY 55
## LMT_HourlyAvgPayRangeAdvertised_Indeed LMT_AnualAvgPayAdvertised_Indeed
## 1 34.00250 76209.6
## 2 28.48387 40000.0
## 3 25.00000 32500.0
## Zillow_2BR_10cityAverageHomeValue median2018IncomeByState
## 1 252568.0 70315
## 2 193815.5 60782
## 3 240742.7 61584
## total_state_population percent_black percent_white percent_two_or_more
## 1 5611179 6.6 82.5 3.1
## 2 626299 1.2 94.1 2.0
## 3 577737 0.6 91.5 2.4
## percent_Native_American percent_Asian percent_Pacific_Islander percent_Latino
## 1 1.1 4.9 0.0 5.5
## 2 0.3 1.9 0.0 2.0
## 3 2.8 1.0 0.2 10.0
## chiropractor_businessListings wellness.clinic_businessListings
## 1 1542 1262
## 2 714 245
## 3 260 177
## massage.spa_businessListings yoga_businessListings gym_businessListings
## 1 1415 1257 1302
## 2 851 448 520
## 3 317 184 138
## coffee_businessListings health.food_businessListings
## 1 1343 1328
## 2 589 575
## 3 188 193
## hair.salon_businessListings tanning_businessListings
## 1 2286 1165
## 2 1070 110
## 3 562 68
## TwoBedroomApartment_Listings._10cities Rent2BR2BA_MinPrice._10cities
## 1 233 1919.225
## 2 28 1699.231
## 3 30 846.360
## Rent2BR2BA_MaxPrice._10cities Rent2BR2BA_AvgPrice._10cities
## 1 2928.744 2347.035
## 2 1768.750 1709.077
## 3 1013.000 875.080
Lets also put together the data for the 3 city information.
nonReg3 <- filter(threeCities,threeCities$stateAbbreviation %in% nonRegulatedList)
nr3_jobsAvail <- nonReg3[,c(1,33:45,106:118)]
nr3_jobsAvail
## stateAbbreviation LMT_AvgJobsListed_IndeedFirst5pages
## 1 MN 176
## 2 VT 62
## 3 WY 26
## LMT_HourlyAvgPayRangeAdvertised_Indeed LMT_AnualAvgPayAdvertised_Indeed
## 1 37.14489 49247.55
## 2 20.88710 NA
## 3 39.54545 NA
## Zillow_2BR_3cityAverageHomeValue median2018IncomeByState
## 1 187554.0 70315
## 2 187487.5 60782
## 3 181051.5 61584
## total_state_population percent_black percent_white percent_two_or_more
## 1 5611179 6.6 82.5 3.1
## 2 626299 1.2 94.1 2.0
## 3 577737 0.6 91.5 2.4
## percent_Native_American percent_Asian percent_Pacific_Islander percent_Latino
## 1 1.1 4.9 0.0 5.5
## 2 0.3 1.9 0.0 2.0
## 3 2.8 1.0 0.2 10.0
## chiropractor_businessListings wellness.clinic_businessListings
## 1 460 332
## 2 294 92
## 3 115 36
## massage_businessListings yoga_businessListings gym_businessListings
## 1 393 331 361
## 2 243 185 214
## 3 123 51 62
## coffee_businessListings health.food_businessListings
## 1 375 350
## 2 238 222
## 3 82 92
## hair.salon_businessListings tanning_businessListings
## 1 459 323
## 2 402 48
## 3 253 32
## TwoBedroomApartment_Listings Rent2BR2BA_MinPrice Rent2BR2BA_MaxPrice
## 1 150 2013.122 3244.016
## 2 9 1705.875 1750.000
## 3 11 959.375 1034.333
## Rent2BR2BA_AvgPrice
## 1 2526.189
## 2 1725.125
## 3 972.375
nr3_jobsAvail$LMT_AnualAvgPayAdvertised_Indeed <- ifelse(is.na(nr3_jobsAvail$LMT_AnualAvgPayAdvertised_Indeed),
nr3_jobsAvail$LMT_HourlyAvgPayRangeAdvertised_Indeed*25*52,
nr3_jobsAvail$LMT_AnualAvgPayAdvertised_Indeed)
nr3_jobsAvail
## stateAbbreviation LMT_AvgJobsListed_IndeedFirst5pages
## 1 MN 176
## 2 VT 62
## 3 WY 26
## LMT_HourlyAvgPayRangeAdvertised_Indeed LMT_AnualAvgPayAdvertised_Indeed
## 1 37.14489 49247.55
## 2 20.88710 27153.23
## 3 39.54545 51409.09
## Zillow_2BR_3cityAverageHomeValue median2018IncomeByState
## 1 187554.0 70315
## 2 187487.5 60782
## 3 181051.5 61584
## total_state_population percent_black percent_white percent_two_or_more
## 1 5611179 6.6 82.5 3.1
## 2 626299 1.2 94.1 2.0
## 3 577737 0.6 91.5 2.4
## percent_Native_American percent_Asian percent_Pacific_Islander percent_Latino
## 1 1.1 4.9 0.0 5.5
## 2 0.3 1.9 0.0 2.0
## 3 2.8 1.0 0.2 10.0
## chiropractor_businessListings wellness.clinic_businessListings
## 1 460 332
## 2 294 92
## 3 115 36
## massage_businessListings yoga_businessListings gym_businessListings
## 1 393 331 361
## 2 243 185 214
## 3 123 51 62
## coffee_businessListings health.food_businessListings
## 1 375 350
## 2 238 222
## 3 82 92
## hair.salon_businessListings tanning_businessListings
## 1 459 323
## 2 402 48
## 3 253 32
## TwoBedroomApartment_Listings Rent2BR2BA_MinPrice Rent2BR2BA_MaxPrice
## 1 150 2013.122 3244.016
## 2 9 1705.875 1750.000
## 3 11 959.375 1034.333
## Rent2BR2BA_AvgPrice
## 1 2526.189
## 2 1725.125
## 3 972.375
Lets look at the race demographics of these states that aren’t regulated first.It doesn’t matter what table we get it, because this information is based on state data not on city data. It could be that some or most races are distributed more in one city than represented as a whole for the entire state. Because larger cities usually have hubs of small ethnic groups like San Francisco or Los Angeles. Some rural towns might have 0% Asians, but another town 20 miles away could have 25% Asians in their demographics, while the state might show there are only 1% Asians. This helps to gauge how diverse the populations are in each state, but not how the distributions are in regions of the state.
nr3_race <- nr3_jobsAvail[,c(1,7:14)]
nr3_race1 <- gather(nr3_race,key='race', value='percent',3:9)
nr3_race1 <- nr3_race1[order(nr3_race1$stateAbbreviation),]
nr3_MN <- subset(nr3_race1, nr3_race1$stateAbbreviation=='MN')
nr3_VT <- subset(nr3_race1, nr3_race1$stateAbbreviation=='VT')
nr3_WY <- subset(nr3_race1, nr3_race1$stateAbbreviation=='WY')
gg1 <- ggplot(data = nr3_MN, aes(y=nr3_MN$percent, x=nr3_MN$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MN Race Distribution of each non-Regulated State of LMT')+
ylab(NULL)+
xlab(NULL)
gg2 <- ggplot(data = nr3_VT, aes(y=nr3_VT$percent, x=nr3_MN$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('VT Race Distribution of each non-Regulated State of LMT')+
ylab(NULL)+
xlab(NULL)
gg3 <- ggplot(data = nr3_WY, aes(y=nr3_WY$percent, x=nr3_MN$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('WY Race Distribution of each non-Regulated State of LMT')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg1, gg2, gg3, ncol = 3)
Now, lets look at the number of jobs available in the top 3 most populated cities of these non-regulated massage therapy states.
nr3_ja <- nr3_jobsAvail[,c(1,2,15:17)]
nr10_ja <- nr10_jobsAvail[,c(1,2,15:17)]
nr3_ja2 <- gather(nr3_ja, key='listings',value='numberListed',2:5)
nr10_ja2 <- gather(nr10_ja, key='listings', value='numberListed', 2:5)
nr3_ja2_MN <- subset(nr3_ja2, nr3_ja2$stateAbbreviation=='MN')
nr3_ja2_VT <- subset(nr3_ja2, nr3_ja2$stateAbbreviation=='VT')
nr3_ja2_WY <- subset(nr3_ja2, nr3_ja2$stateAbbreviation=='WY')
gg4 <- ggplot(data = nr3_ja2_MN, aes(y=nr3_ja2_MN$numberListed, x=nr3_ja2_MN$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MN LMT and similar business listings')+
ylab(NULL)+
xlab(NULL)
gg5 <- ggplot(data = nr3_ja2_VT, aes(y=nr3_ja2_VT$numberListed, x=nr3_ja2_MN$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('VT LMT and similar business listings')+
ylab(NULL)+
xlab(NULL)
gg6 <- ggplot(data = nr3_ja2_WY, aes(y=nr3_ja2_WY$numberListed, x=nr3_ja2_WY$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('WY LMT and similar business listings')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg4, gg5, gg6, ncol = 3)
There are quite a bit of massage type businesses listed in yellow pages and LMT jobs advertised on Indeed in these three states that don’t regulate massage therapy at the state level.
That was for the three most populated cities in each of these states, now lets look at the data from the ten most populated cities in each of these states.
nr10_ja2_MN <- subset(nr10_ja2, nr10_ja2$stateAbbreviation=='MN')
nr10_ja2_VT <- subset(nr10_ja2, nr10_ja2$stateAbbreviation=='VT')
nr10_ja2_WY <- subset(nr10_ja2, nr10_ja2$stateAbbreviation=='WY')
gg7 <- ggplot(data = nr10_ja2_MN,
aes(y=nr10_ja2_MN$numberListed, x=nr10_ja2_MN$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MN LMT and similar business listings')+
ylab(NULL)+
xlab(NULL)
gg8 <- ggplot(data = nr10_ja2_VT, aes(y=nr10_ja2_VT$numberListed,
x=nr10_ja2_MN$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('VT LMT and similar business listings')+
ylab(NULL)+
xlab(NULL)
gg9 <- ggplot(data = nr10_ja2_WY, aes(y=nr10_ja2_WY$numberListed,
x=nr10_ja2_WY$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('WY LMT and similar business listings')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg7, gg8, gg9, ncol = 3)
Lets look at the advertised pay for LMTs in these three states on an annual basis compared to the median annual salary for each state a couple of years ago in 2018, and with the average home value and average low price of the two bedroom and two bathroom apartments in each of these states by their three and ten most populated cities.Lets turn the apartments monthly cost to an annual cost to put it on the same scale value as the other factors. Also, the home value is off the scale so lets simulate an average annual payment with 5% interest on the home value as the amount paid annually for a home in these states on average.
nr3_living <- nr3_jobsAvail[,c(1,4,5,6,25)]
nr3_living$Rent2BR2BA_MinPrice <- nr3_living$Rent2BR2BA_MinPrice*12
nr3_living$Zillow_2BR_3cityAverageHomeValue <- (nr3_living$Zillow_2BR_3cityAverageHomeValue/20)+ .05*(nr3_living$Zillow_2BR_3cityAverageHomeValue)
nr10_living <- nr10_jobsAvail[,c(1,4,5,6,25)]
nr10_living$Rent2BR2BA_MinPrice._10cities <- nr10_living$Rent2BR2BA_MinPrice._10cities*12
nr10_living$Zillow_2BR_10cityAverageHomeValue <- (nr10_living$Zillow_2BR_10cityAverageHomeValue/20)+.05*(nr10_living$Zillow_2BR_10cityAverageHomeValue)
nr3_valueLiving <- gather(nr3_living, key='living', value='price', 2:5)
nr10_valueLiving <- gather(nr10_living, key='living', value='price', 2:5)
nr3_valueLiving_MN <- subset(nr3_valueLiving, nr3_valueLiving$stateAbbreviation=='MN')
nr3_valueLiving_VT <- subset(nr3_valueLiving, nr3_valueLiving$stateAbbreviation=='VT')
nr3_valueLiving_WY <- subset(nr3_valueLiving, nr3_valueLiving$stateAbbreviation=='WY')
nr10_valueLiving_MN <- subset(nr10_valueLiving, nr10_valueLiving$stateAbbreviation=='MN')
nr10_valueLiving_VT <- subset(nr10_valueLiving, nr10_valueLiving$stateAbbreviation=='VT')
nr10_valueLiving_WY <- subset(nr10_valueLiving, nr10_valueLiving$stateAbbreviation=='WY')
Lets look at the three city data on living costs and pay for LMTs.
gg10 <- ggplot(data = nr3_valueLiving_MN,
aes(y=nr3_valueLiving_MN$price, x=nr3_valueLiving_MN$living)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000)) +
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MN Living')+
ylab(NULL)+
xlab(NULL)
gg11 <- ggplot(data = nr3_valueLiving_VT,
aes(y=nr3_valueLiving_VT$price, x=nr3_valueLiving_VT$living))+
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000)) +
theme(legend.position="bottom") +
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('VT Living')+
ylab(NULL)+
xlab(NULL)
gg12 <- ggplot(data = nr3_valueLiving_WY,
aes(y=nr3_valueLiving_WY$price, x=nr3_valueLiving_WY$living)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000)) +
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('WY Living')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg10, gg11, gg12, ncol = 3)
Interestingly, Wyoming seems to have cheaper rent than mortgage or home ownership.Also, in Minnesota the LMTs make more than the median income for the state two years ago, but less than the median income in Vermont and Wyoming.The median income is nearly double that of LMT annual pay in Vermont and in Wyoming. These are the states that don’t have a state massage therapy board in place for their massage therapists.
Now lets look at the ten city data:
gg13 <- ggplot(data = nr10_valueLiving_MN,
aes(y=nr10_valueLiving_MN$price, x=nr10_valueLiving_MN$living)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000)) +
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MN Living')+
ylab(NULL)+
xlab(NULL)
gg14 <- ggplot(data = nr10_valueLiving_VT,
aes(y=nr10_valueLiving_VT$price, x=nr10_valueLiving_VT$living))+
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000)) +
theme(legend.position="bottom") +
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('VT Living')+
ylab(NULL)+
xlab(NULL)
gg15 <- ggplot(data = nr10_valueLiving_WY,
aes(y=nr10_valueLiving_WY$price, x=nr10_valueLiving_WY$living)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000)) +
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('WY Living')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg13, gg14, gg15, ncol = 3)
When looking at the data from the ten most populated cities in each of these non-regulated massage states, we don’t see much change in comparisons state to state. The LMT pay is still more than the median income in Minnesota, and less in Vermont and Wyoming. But the gap isn’t as large in Vermont between LMT pay and the state median pay as it was using just the three most populated cities. Also, in Wyoming rent is still cheaper than monthly mortgage on a home at current prices, but in Minnesota the rent is also cheaper than a monthly mortgage when using ten cities instead of three. This makes sense, as some cities are much more expensive to live in do to rents than the smaller towns.
Those charts and analysis results were from the non-regulated massage therapy states, but we also have more living analysis to do for LMTs in the other states that require more than 500 hours, a minimum of 500 hours, accept endorsements, and more.
Next, lets look at those states that accept endorsements from other states for licensing their massage therapists. We will compare three states in regions of the US that are in different locations, much like the distance between WY, MN, and VT were spread out from the upper west US, to the mid-west, and the east respectively.
Lets first recall the list of those endorsed states and pick three from the list that require more than 500 hours of education, and three that are from states that require a minimum of 500 hours of education or less.
endorsedAnd500PlusList
## [1] "AZ" "CT" "IL" "MS" "NE" "NM" "ND" "OH" "OR" "PA" "UT" "WI"
From the above, we see the 12 states that require more than 500 hours of education but are willing to offer out of state LMT endorsements. They are all pretty spread out except for AZ and NM which are neighbors and OR and UT are neighbors as well. Lets choose IL by a great lake, MS in the south by the Gulf of Mexico, and AZ in the desert state of the western US.
Lets also select three spread out states that are from endorsed states that require less than 500 hours of education.
endorsedList[!(endorsedList %in% endorsedAnd500PlusList)]
## [1] "CO" "ID" "LA" "MT" "NJ" "NC" "OK" "RI" "SC" "SD" "TX" "VA" "WA" "WV"
There are 14 states that endorse massage therapists based on out of state licenses held but that are also states requiring less than or at a minimum 500 hours of massage education. In total there are 26 states that endorse out of state massage therapists. Lets select three states from above that are spread out similarly to the last three states with one in the desert, one in the great lakes area, and one in the alligator regions or swamp land regions. I am going to select the rocky mountain region of CO or Colorado because there is no desert region in this list, the eastern region of NJ or New Jersey, and the swamp region of LA or Louisiana.
Our endorsed states with more than 500 hours education required are: - AZ - IL - MS And our states with endorsements accepted but requiring less than 500 hours are: - LA - CO - NJ
Lets create our subsets from the 10 city and 3 city data tables for those six states above.
sixEndorsed <- c('AZ','IL','MS','LA','CO','NJ')
sixEndorsedDT_10 <- filter(tenCities, tenCities$stateAbbreviation %in% sixEndorsed)
sixEndorsedDT_3 <- filter(threeCities, threeCities$stateAbbreviation %in% sixEndorsed)
We will select only those columns we will likely use.
sixEndorsed_10_dt <- sixEndorsedDT_10[,c(1,33:45,106:116)]
sixEndorsed_3_dt <- sixEndorsedDT_3[,c(1,33:45,106:116)]
Lets change the scale of the house value to that of amount paid in mortgage approximately every year based on the home value, and also change the average of all minimum monthly rents to the amount paid annually in rent based on the average minimum cost of a two bedroom and two bath apartment. Lets also do this for the annual salary of an LMT if it is not listed as we did all of these steps with the non-regulated states.
sixEndorsed_10_dt$Zillow_2BR_10cityAverageHomeValue <-
(sixEndorsed_10_dt$Zillow_2BR_10cityAverageHomeValue/20) +
(.05)*(sixEndorsed_10_dt$Zillow_2BR_10cityAverageHomeValue/20)
sixEndorsed_3_dt$Zillow_2BR_3cityAverageHomeValue <-
(sixEndorsed_3_dt$Zillow_2BR_3cityAverageHomeValue/20) +
(.05)*(sixEndorsed_3_dt$Zillow_2BR_3cityAverageHomeValue/20)
sixEndorsed_10_dt$Rent2BR2BA_MinPrice._10cities <-
(sixEndorsed_10_dt$Rent2BR2BA_MinPrice._10cities)*(12)
sixEndorsed_3_dt$Rent2BR2BA_MinPrice <-
(sixEndorsed_3_dt$Rent2BR2BA_MinPrice)*(12)
sixEndorsed_10_dt$LMT_AnualAvgPayAdvertised_Indeed <-
ifelse(!is.na(sixEndorsed_10_dt$LMT_AnualAvgPayAdvertised_Indeed),
sixEndorsed_10_dt$LMT_AnualAvgPayAdvertised_Indeed,
(sixEndorsed_10_dt$LMT_HourlyAvgPayRangeAdvertised_Indeed)*(12))
sixEndorsed_3_dt$LMT_AnualAvgPayAdvertised_Indeed <-
ifelse(!is.na(sixEndorsed_3_dt$LMT_AnualAvgPayAdvertised_Indeed),
sixEndorsed_3_dt$LMT_AnualAvgPayAdvertised_Indeed, (sixEndorsed_3_dt$LMT_HourlyAvgPayRangeAdvertised_Indeed)*(40)*(52))
Lets first see how the racial distribution for diversity is in these six states and it doesn’t matter if we use the 10 city or 3 city table because the state demographics is the same.
sixEndorsed_race <- sixEndorsed_3_dt[,c(1,7:14)]
sixEndorsed_race1 <- gather(sixEndorsed_race,key='race', value='percent',3:9)
sixEndorsed_race1 <- sixEndorsed_race1[order(sixEndorsed_race1$stateAbbreviation),]
sixEndorsed_AZ <- subset(sixEndorsed_race1, sixEndorsed_race1$stateAbbreviation=='AZ')
sixEndorsed_IL <- subset(sixEndorsed_race1, sixEndorsed_race1$stateAbbreviation=='IL')
sixEndorsed_MS <- subset(sixEndorsed_race1, sixEndorsed_race1$stateAbbreviation=='MS')
sixEndorsed_CO <- subset(sixEndorsed_race1, sixEndorsed_race1$stateAbbreviation=='CO')
sixEndorsed_LA <- subset(sixEndorsed_race1, sixEndorsed_race1$stateAbbreviation=='LA')
sixEndorsed_NJ <- subset(sixEndorsed_race1, sixEndorsed_race1$stateAbbreviation=='NJ')
sixEndorsed_race
## stateAbbreviation total_state_population percent_black percent_white
## 1 AZ 7171646 4.7 78.0
## 2 CO 5695564 4.2 84.1
## 3 IL 12741080 14.1 71.7
## 4 LA 4659978 32.4 61.7
## 5 MS 2986530 38.0 58.1
## 6 NJ 8908520 13.6 66.9
## percent_two_or_more percent_Native_American percent_Asian
## 1 4.0 4.6 3.3
## 2 4.0 1.0 3.2
## 3 2.7 0.3 5.6
## 4 2.3 0.6 1.6
## 5 1.5 0.4 0.9
## 6 2.8 0.2 9.7
## percent_Pacific_Islander percent_Latino
## 1 0.2 31.6
## 2 0.1 21.7
## 3 0.0 17.3
## 4 0.0 5.1
## 5 0.0 2.9
## 6 0.0 20.6
gg21 <- ggplot(data = sixEndorsed_AZ, aes(y=sixEndorsed_AZ$percent, x=sixEndorsed_AZ$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 100))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ Race;Endorsed 500+')+
ylab(NULL)+
xlab(NULL)
gg22 <- ggplot(data = sixEndorsed_IL, aes(y=sixEndorsed_IL$percent, x=sixEndorsed_IL$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 100))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL Race;Endorsed 500+')+
ylab(NULL)+
xlab(NULL)
gg23 <- ggplot(data = sixEndorsed_MS, aes(y=sixEndorsed_MS$percent, x=sixEndorsed_MS$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 100))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS Race;Endorsed 500+')+
ylab(NULL)+
xlab(NULL)
gg24 <- ggplot(data = sixEndorsed_CO, aes(y=sixEndorsed_CO$percent, x=sixEndorsed_CO$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 100))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO Race;Endorsed 500 or Less')+
ylab(NULL)+
xlab(NULL)
gg25 <- ggplot(data = sixEndorsed_LA, aes(y=sixEndorsed_LA$percent, x=sixEndorsed_LA$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 100))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA Race;Endorsed 500 or Less')+
ylab(NULL)+
xlab(NULL)
gg26 <- ggplot(data = sixEndorsed_NJ, aes(y=sixEndorsed_NJ$percent, x=sixEndorsed_NJ$race)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 100))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ Race;Endorsed 500 or Less')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg21, gg22, gg23, ncol = 3)
grid.arrange(gg24,gg25,gg26, ncol=3)
Now, lets look at the number of jobs available and the number of business listings of similar businesses that LMTs can work. For this we will compare using the three most populated cities in each of these states to the ten most populated cities in each state.
sixEndorsed_10_dt_Listings <- sixEndorsed_10_dt[,c(1,2,15:17)]
sixEndorsed_3_dt_Listings <- sixEndorsed_3_dt[,c(1,2,15:17)]
sixEndorsed_10_dt_Listed <- gather(sixEndorsed_10_dt_Listings,
key='listings',value='numberListed',2:5)
sixEndorsed_3_dt_Listed <- gather(sixEndorsed_3_dt_Listings, key='listings',
value='numberListed', 2:5)
sixEndorsed_3_dt_Listed_AZ <- subset(sixEndorsed_3_dt_Listed, sixEndorsed_3_dt_Listed$stateAbbreviation=='AZ')
sixEndorsed_3_dt_Listed_IL <- subset(sixEndorsed_3_dt_Listed, sixEndorsed_3_dt_Listed$stateAbbreviation=='IL')
sixEndorsed_3_dt_Listed_MS <- subset(sixEndorsed_3_dt_Listed, sixEndorsed_3_dt_Listed$stateAbbreviation=='MS')
sixEndorsed_3_dt_Listed_CO <- subset(sixEndorsed_3_dt_Listed, sixEndorsed_3_dt_Listed$stateAbbreviation=='CO')
sixEndorsed_3_dt_Listed_LA <- subset(sixEndorsed_3_dt_Listed, sixEndorsed_3_dt_Listed$stateAbbreviation=='LA')
sixEndorsed_3_dt_Listed_NJ <- subset(sixEndorsed_3_dt_Listed, sixEndorsed_3_dt_Listed$stateAbbreviation=='NJ')
sixEndorsed_10_dt_Listed_AZ <- subset(sixEndorsed_10_dt_Listed, sixEndorsed_10_dt_Listed$stateAbbreviation=='AZ')
sixEndorsed_10_dt_Listed_IL <- subset(sixEndorsed_10_dt_Listed, sixEndorsed_10_dt_Listed$stateAbbreviation=='IL')
sixEndorsed_10_dt_Listed_MS <- subset(sixEndorsed_10_dt_Listed, sixEndorsed_10_dt_Listed$stateAbbreviation=='MS')
sixEndorsed_10_dt_Listed_CO <- subset(sixEndorsed_10_dt_Listed, sixEndorsed_10_dt_Listed$stateAbbreviation=='CO')
sixEndorsed_10_dt_Listed_LA <- subset(sixEndorsed_10_dt_Listed, sixEndorsed_10_dt_Listed$stateAbbreviation=='LA')
sixEndorsed_10_dt_Listed_NJ <- subset(sixEndorsed_10_dt_Listed, sixEndorsed_10_dt_Listed$stateAbbreviation=='NJ')
gg27 <- ggplot(data = sixEndorsed_10_dt_Listed_AZ, aes(y=sixEndorsed_10_dt_Listed_AZ$numberListed, x=sixEndorsed_10_dt_Listed_AZ$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ ')+
ylab(NULL)+
xlab(NULL)
gg28 <- ggplot(data = sixEndorsed_10_dt_Listed_IL, aes(y=sixEndorsed_10_dt_Listed_IL$numberListed, x=sixEndorsed_10_dt_Listed_IL$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL ')+
ylab(NULL)+
xlab(NULL)
gg29 <- ggplot(data = sixEndorsed_10_dt_Listed_MS, aes(y=sixEndorsed_10_dt_Listed_MS$numberListed, x=sixEndorsed_10_dt_Listed_MS$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS ')+
ylab(NULL)+
xlab(NULL)
gg30 <- ggplot(data = sixEndorsed_10_dt_Listed_CO, aes(y=sixEndorsed_10_dt_Listed_CO$numberListed, x=sixEndorsed_10_dt_Listed_CO$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO ')+
ylab(NULL)+
xlab(NULL)
gg31 <- ggplot(data = sixEndorsed_10_dt_Listed_LA, aes(y=sixEndorsed_10_dt_Listed_LA$numberListed, x=sixEndorsed_10_dt_Listed_LA$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA ')+
ylab(NULL)+
xlab(NULL)
gg32 <- ggplot(data = sixEndorsed_10_dt_Listed_NJ, aes(y=sixEndorsed_10_dt_Listed_NJ$numberListed, x=sixEndorsed_10_dt_Listed_NJ$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 1600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ ')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg27, gg28, gg29, ncol = 3)
grid.arrange(gg30,gg31,gg32, ncol=3)
The above showed the number of jobs available or advertised for LMT and the number of business listings for businesses that use LMTs in their normal operations, such as chiropractic, massage spas, and wellness clinics. It also showed the ten most populated cities in each of the selected states for listings. Note that in the above 10 city listings that there are fewer LMT jobs listed or advertised in the two swamp states of LA and MS or southern alligator regions.In the swamp regions there are less natural parks or water resources like lakes to recreation in due to alligators, so it is possible more of the residents want to take care of their health by getting regular massages. They could have plenty of massage therapists and have an adequate supply or rotation of LMTs moving from business to business within their communities. There are also more massage businesses listed in these two southern swamp states than chiropractic or wellness clinics. The desert and midwestern states and eastern state have more chiropractic listings than southern swamp states. This could also be due to the number of auto collisions in these states and the need for chiropractic adjustments to alleviate pain associated with auto collisions.
Lets look at the three most populated cities in each of these states and see if they are similar in listings.
gg33 <- ggplot(data = sixEndorsed_3_dt_Listed_AZ, aes(y=sixEndorsed_3_dt_Listed_AZ$numberListed, x=sixEndorsed_3_dt_Listed_AZ$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ ')+
ylab(NULL)+
xlab(NULL)
gg34 <- ggplot(data = sixEndorsed_3_dt_Listed_IL, aes(y=sixEndorsed_3_dt_Listed_IL$numberListed, x=sixEndorsed_3_dt_Listed_IL$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL ')+
ylab(NULL)+
xlab(NULL)
gg35 <- ggplot(data = sixEndorsed_3_dt_Listed_MS, aes(y=sixEndorsed_3_dt_Listed_MS$numberListed, x=sixEndorsed_3_dt_Listed_MS$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS ')+
ylab(NULL)+
xlab(NULL)
gg36 <- ggplot(data = sixEndorsed_3_dt_Listed_CO, aes(y=sixEndorsed_3_dt_Listed_CO$numberListed, x=sixEndorsed_3_dt_Listed_CO$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO ')+
ylab(NULL)+
xlab(NULL)
gg37 <- ggplot(data = sixEndorsed_3_dt_Listed_LA, aes(y=sixEndorsed_3_dt_Listed_LA$numberListed, x=sixEndorsed_3_dt_Listed_LA$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA ')+
ylab(NULL)+
xlab(NULL)
gg38 <- ggplot(data = sixEndorsed_3_dt_Listed_NJ, aes(y=sixEndorsed_3_dt_Listed_NJ$numberListed, x=sixEndorsed_3_dt_Listed_NJ$listings)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 600))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ ')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg33, gg34, gg35, ncol = 3)
grid.arrange(gg36,gg37,gg38, ncol=3)
There is a definite change or noticeable difference when looking at the three most populated cities’ listings rather than the ten most populated aggregate sum of business and LMT jobs listed. We see that in the city or more urban areas there is now all more listings for chiropractors instead of massage businesses. In LA and MS, when we used the 10 city listings we saw more massage businesses listed overall. But now, it looks like every state has more chiropractic listings. There are still fewer LMT jobs available in the two swamp states selected.
Now lets look at the cost of living.
sixEndorsed_living10 <- sixEndorsed_10_dt[,c(1,4,5,6,25)]
sixEndorsed_living3 <- sixEndorsed_3_dt[,c(1,4,5,6,25)]
sixEndorsed_living10
## stateAbbreviation LMT_AnualAvgPayAdvertised_Indeed
## 1 AZ 74146.16
## 2 CO 43002.34
## 3 IL 51341.99
## 4 LA 76900.00
## 5 MS 48508.52
## 6 NJ 61327.10
## Zillow_2BR_10cityAverageHomeValue median2018IncomeByState
## 1 12617.655 59246
## 2 17186.685 71953
## 3 10641.190 65030
## 4 7434.518 47905
## 5 4265.910 51049
## 6 13648.939 81740
## Rent2BR2BA_MinPrice._10cities
## 1 15683.52
## 2 20430.51
## 3 24840.29
## 4 13116.66
## 5 11013.66
## 6 33596.67
sixEndorsed_living3
## stateAbbreviation LMT_AnualAvgPayAdvertised_Indeed
## 1 AZ 50748.89
## 2 CO 43500.00
## 3 IL 52865.80
## 4 LA 80032.18
## 5 MS 47651.89
## 6 NJ 66000.00
## Zillow_2BR_3cityAverageHomeValue median2018IncomeByState Rent2BR2BA_MinPrice
## 1 10523.468 59246 15058.93
## 2 14010.517 71953 20956.06
## 3 9693.994 65030 29692.29
## 4 4270.481 47905 14146.76
## 5 5099.220 51049 11096.46
## 6 11898.443 81740 38032.63
SE10 <- gather(sixEndorsed_living10, key='necessity', value='cost', 2:5)
SE3 <- gather(sixEndorsed_living3, key='necessity', value='cost', 2:5)
sixEndorsed_living10_AZ <- subset(SE10, SE10$stateAbbreviation=='AZ')
sixEndorsed_living10_IL <- subset(SE10, SE10$stateAbbreviation=='IL')
sixEndorsed_living10_MS <- subset(SE10, SE10$stateAbbreviation=='MS')
sixEndorsed_living10_CO <- subset(SE10, SE10$stateAbbreviation=='CO')
sixEndorsed_living10_LA <- subset(SE10, SE10$stateAbbreviation=='LA')
sixEndorsed_living10_NJ <- subset(SE10, SE10$stateAbbreviation=='NJ')
sixEndorsed_living3_AZ <- subset(SE3, SE3$stateAbbreviation=='AZ')
sixEndorsed_living3_IL <- subset(SE3, SE3$stateAbbreviation=='IL')
sixEndorsed_living3_MS <- subset(SE3, SE3$stateAbbreviation=='MS')
sixEndorsed_living3_CO <- subset(SE3, SE3$stateAbbreviation=='CO')
sixEndorsed_living3_LA <- subset(SE3, SE3$stateAbbreviation=='LA')
sixEndorsed_living3_NJ <- subset(SE3, SE3$stateAbbreviation=='NJ')
gg39 <- ggplot(data = sixEndorsed_living10_AZ, aes(y=sixEndorsed_living10_AZ$cost, x=sixEndorsed_living10_AZ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ ')+
ylab(NULL)+
xlab(NULL)
gg40 <- ggplot(data = sixEndorsed_living10_IL, aes(y=sixEndorsed_living10_IL$cost, x=sixEndorsed_living10_IL$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL ')+
ylab(NULL)+
xlab(NULL)
gg41 <- ggplot(data = sixEndorsed_living10_MS, aes(y=sixEndorsed_living10_MS$cost, x=sixEndorsed_living10_MS$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS ')+
ylab(NULL)+
xlab(NULL)
gg42 <- ggplot(data = sixEndorsed_living10_CO, aes(y=sixEndorsed_living10_CO$cost, x=sixEndorsed_living10_CO$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO ')+
ylab(NULL)+
xlab(NULL)
gg43 <- ggplot(data = sixEndorsed_living10_LA, aes(y=sixEndorsed_living10_LA$cost, x=sixEndorsed_living10_LA$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA ')+
ylab(NULL)+
xlab(NULL)
gg44 <- ggplot(data = sixEndorsed_living10_NJ, aes(y=sixEndorsed_living10_NJ$cost, x=sixEndorsed_living10_NJ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ ')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg39, gg40, gg41, ncol = 3)
grid.arrange(gg42, gg43, gg44, ncol = 3)
In the above, we used the ten most populated cities of each state’s living values. In AZ and LA the LMT annual income is more than the median income and close to the same value for Mississippi. Rent is more than home ownership in every state. In Colorado, LMTs make much less than the median income compared to the other states selected. When we recall the number of LMT jobs available in CO compared to the other states, there were a fair amount of LMT jobs available and much more than were advertised in Louisiana and Mississippi.
The above charts show the ten most populated cities’ living values for annual advertised pay for LMTs, the median income for those states based on 2018 values, the amount spent on mortgage compared to renting a two bedroom and two bathroom apartment in these states. The annual pay is probably what was put on the advertised job listing based on 40 hours per week, and realistically the pay fluctuates for LMTs to figure in gratuities, working full time for an LMT is 25-30 hours of massage a week, and hours not spent massaging if working is usually at the minimum wage or closer to it.
Lets look at the three city living values before altering the annual pay to 25 hours a week instead of 40 hours per week.
gg45 <- ggplot(data = sixEndorsed_living3_AZ, aes(y=sixEndorsed_living3_AZ$cost, x=sixEndorsed_living3_AZ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ ')+
ylab(NULL)+
xlab(NULL)
gg46 <- ggplot(data = sixEndorsed_living3_IL, aes(y=sixEndorsed_living3_IL$cost, x=sixEndorsed_living3_IL$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL ')+
ylab(NULL)+
xlab(NULL)
gg47 <- ggplot(data = sixEndorsed_living3_MS, aes(y=sixEndorsed_living3_MS$cost, x=sixEndorsed_living3_MS$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS ')+
ylab(NULL)+
xlab(NULL)
gg48 <- ggplot(data = sixEndorsed_living3_CO, aes(y=sixEndorsed_living3_CO$cost, x=sixEndorsed_living3_CO$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO ')+
ylab(NULL)+
xlab(NULL)
gg49 <- ggplot(data = sixEndorsed_living3_LA, aes(y=sixEndorsed_living3_LA$cost, x=sixEndorsed_living3_LA$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA ')+
ylab(NULL)+
xlab(NULL)
gg50 <- ggplot(data = sixEndorsed_living3_NJ, aes(y=sixEndorsed_living3_NJ$cost, x=sixEndorsed_living3_NJ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ ')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg45, gg46, gg47, ncol = 3)
grid.arrange(gg48, gg49, gg50, ncol = 3)
In the three city living values, home ownership is very affordable in Louisiana or LA, and LMTs might have less jobs available but they make more than the median income for the state. Rent is more expensive in each of these states than home ownership. In every state other than LA the median income is more than the LMT annual pay, and much lower for LMTs in CO than the median income. But AZ and MS LMTs make almost as much as the median income for their states.
Lets change these values for annual salary to 25 hours per week based on hourly advertised pay that likely includes approximations on gratuities. And then we will look at the living values for the 10 city and 3 city averages.
sixEndorsed_living10$LMT_AnualAvgPayAdvertised_Indeed <-
(((sixEndorsed_living10$LMT_AnualAvgPayAdvertised_Indeed)/52)/40)*25*52
sixEndorsed_living3$LMT_AnualAvgPayAdvertised_Indeed <-
(((sixEndorsed_living3$LMT_AnualAvgPayAdvertised_Indeed)/52)/40)*25*52
SE10 <- gather(sixEndorsed_living10, key='necessity', value='cost', 2:5)
SE3 <- gather(sixEndorsed_living3, key='necessity', value='cost', 2:5)
sixEndorsed_living10_AZ <- subset(SE10, SE10$stateAbbreviation=='AZ')
sixEndorsed_living10_IL <- subset(SE10, SE10$stateAbbreviation=='IL')
sixEndorsed_living10_MS <- subset(SE10, SE10$stateAbbreviation=='MS')
sixEndorsed_living10_CO <- subset(SE10, SE10$stateAbbreviation=='CO')
sixEndorsed_living10_LA <- subset(SE10, SE10$stateAbbreviation=='LA')
sixEndorsed_living10_NJ <- subset(SE10, SE10$stateAbbreviation=='NJ')
sixEndorsed_living3_AZ <- subset(SE3, SE3$stateAbbreviation=='AZ')
sixEndorsed_living3_IL <- subset(SE3, SE3$stateAbbreviation=='IL')
sixEndorsed_living3_MS <- subset(SE3, SE3$stateAbbreviation=='MS')
sixEndorsed_living3_CO <- subset(SE3, SE3$stateAbbreviation=='CO')
sixEndorsed_living3_LA <- subset(SE3, SE3$stateAbbreviation=='LA')
sixEndorsed_living3_NJ <- subset(SE3, SE3$stateAbbreviation=='NJ')
Now lets see how the living values compare for LMTs and each state by the ten and three most populated cities.
gg39 <- ggplot(data = sixEndorsed_living10_AZ, aes(y=sixEndorsed_living10_AZ$cost, x=sixEndorsed_living10_AZ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ ')+
ylab(NULL)+
xlab(NULL)
gg40 <- ggplot(data = sixEndorsed_living10_IL, aes(y=sixEndorsed_living10_IL$cost, x=sixEndorsed_living10_IL$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL ')+
ylab(NULL)+
xlab(NULL)
gg41 <- ggplot(data = sixEndorsed_living10_MS, aes(y=sixEndorsed_living10_MS$cost, x=sixEndorsed_living10_MS$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS ')+
ylab(NULL)+
xlab(NULL)
gg42 <- ggplot(data = sixEndorsed_living10_CO, aes(y=sixEndorsed_living10_CO$cost, x=sixEndorsed_living10_CO$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO ')+
ylab(NULL)+
xlab(NULL)
gg43 <- ggplot(data = sixEndorsed_living10_LA, aes(y=sixEndorsed_living10_LA$cost, x=sixEndorsed_living10_LA$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA ')+
ylab(NULL)+
xlab(NULL)
gg44 <- ggplot(data = sixEndorsed_living10_NJ, aes(y=sixEndorsed_living10_NJ$cost, x=sixEndorsed_living10_NJ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ ')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg39, gg40, gg41, ncol = 3)
grid.arrange(gg42,gg43,gg44,ncol=3)
When we used realistic schedules for a massage therapist who performs 25 hours of massage a week instead of the 40 hours advertised pay was based on, we see a huge difference in the ten city data charts above. When you compare rent to the realistic annual income of an LMT, New Jersey is not a state that is likely to have an LMT live well off or comfortably as the rent is much more than the LMT annual salary. But states like Arizona, Mississippi, and Louisiana would be much better states for an LMT to live and work in, as the rent is not more than the LMT annual salary and leaves some income to live off of after rent is paid. Lets now look at the three city living values.
gg45 <- ggplot(data = sixEndorsed_living3_AZ, aes(y=sixEndorsed_living3_AZ$cost, x=sixEndorsed_living3_AZ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('AZ ')+
ylab(NULL)+
xlab(NULL)
gg46 <- ggplot(data = sixEndorsed_living3_IL, aes(y=sixEndorsed_living3_IL$cost, x=sixEndorsed_living3_IL$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('IL ')+
ylab(NULL)+
xlab(NULL)
gg47 <- ggplot(data = sixEndorsed_living3_MS, aes(y=sixEndorsed_living3_MS$cost, x=sixEndorsed_living3_MS$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('MS ')+
ylab(NULL)+
xlab(NULL)
gg48 <- ggplot(data = sixEndorsed_living3_CO, aes(y=sixEndorsed_living3_CO$cost, x=sixEndorsed_living3_CO$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_bw()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('CO ')+
ylab(NULL)+
xlab(NULL)
gg49 <- ggplot(data = sixEndorsed_living3_LA, aes(y=sixEndorsed_living3_LA$cost, x=sixEndorsed_living3_LA$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_gray()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('LA ')+
ylab(NULL)+
xlab(NULL)
gg50 <- ggplot(data = sixEndorsed_living3_NJ, aes(y=sixEndorsed_living3_NJ$cost, x=sixEndorsed_living3_NJ$necessity)) +
geom_bar(stat='identity', position=position_dodge())+
scale_fill_brewer(palette='Paired') +
theme_grey()+
coord_cartesian(ylim = c(0, 80000))+
theme(legend.position="bottom")+
theme(axis.text = element_text(colour = "black", angle=90, size = rel(.75)))+
ggtitle('NJ ')+
ylab(NULL)+
xlab(NULL)
grid.arrange(gg45, gg46, gg47, ncol = 3)
grid.arrange(gg48,gg49,gg50,ncol=3)
In the above, we see the more realistic 25 hour work week of an LMT in those states that offer out of state endorsements for LMTs. We see that an LMT would not do well living and working in Colorado, Illinois, or New Jersey as rent is much more than the annual wages but that in AZ an LMT could do possibly ok as rent is just under the annual wages. But if an LMT lived in Louisiana or Mississippi the welfare of an LMT would be good. The 25 hour work week is an average work week for an LMT. Some LMTs do work more than six hours a day and more than 5 days a week and can make closer to the 40 hours of massage a week. The 25 hour work week is more as a bottom line or minimum effort to gauge the labor market and living costs of an LMT in certain states or regions.
There are still more states that weren’t analyzed or compared, such as those that don’t offer out of state endorsement or the other states that do offer out of state endorsements. What about looking at those states with a high massage education requirement and no out of state endorsements. Do those states’ LMTs have a better welfare than other states? We will find out next.