Number of Nonprofit Organizations in Texas, 2005 - 2015

3.13.2019
Deondre' Jones

More from this project:

  1. library(httr)
  2. library(tidyverse)
  3. library(stringr)
  4. library(RCurl)
  5. library(reshape2)
  6. library(RColorBrewer)
  7. library(extrafont)
  8. library(knitr)
  9. library(foreign)
  10. library(kableExtra)
  11. library(grid)
  12. library(gridExtra)
  13.  
  14. stateparam <- "TX"
  15. yearparam <- "2015"
  16.  
  17. #Import reduced NCCS Core File Function
  18. prepbmffile <- function(bmffilepath) {
  19.   output <- read_csv(bmffilepath,
  20.                      col_types = cols_only(EIN = col_character(),
  21.                                            NTEECC = col_character(),
  22.                                            STATE = col_character(),                                         
  23.                                            OUTNCCS = col_character(),
  24.                                            SUBSECCD = col_character(),
  25.                                            FNDNCD = col_character(),
  26.                                            CFILER = col_character(),
  27.                                            CZFILER = col_character(),
  28.                                            CTAXPER = col_character(),
  29.                                            CTOTREV = col_double(),
  30.                                            CASSETS = col_double()
  31.                      ))
  32.   names(output) <- toupper(names(output))
  33.   return(output)
  34. }
  35.  
  36. #Pull in first BMF from next year to get most complete picture at end of previous year
  37. bmf2015 <- prepbmffile("bmf.bm1608.csv")
  38. bmf2005 <- prepbmffile("bmf.bm0601.csv")
  39.  
  40. #Pull state name for selected state
  41. stname <- state.name[grep(as.character(stateparam), state.abb)]
  42.  
  43. #replace for DC
  44. if (stateparam =="DC") {stname <- "Washington, DC"}

Number of Nonprofit Organizations in Texas, 2005 - 2015

  1. OverallT <- function(datayear) {
  2.  
  3.   #Function to pull both years of BMF data
  4.   byear <- function(datayear) {
  5.  
  6.     #get BMF file names:
  7.     bmf1 <- as.character(paste("bmf", (datayear -10), sep =""))
  8.     bmf2 <- as.character(paste("bmf", (datayear), sep =""))
  9.  
  10.     #for each BMF file name, run the following:
  11.     bcomponent <- function(bmfnum, year_of_int){
  12.  
  13.       #get dataset  
  14.       bmf <- get(bmfnum)
  15.  
  16.       #filter by state
  17.       bmf<- bmf %>%
  18.         filter(STATE == as.character(stateparam))
  19.  
  20.       #filter out out-of-scope cases
  21.       bmf<- bmf %>%
  22.         filter(OUTNCCS != "OUT")
  23.  
  24.       #calculate all registered nonprofits
  25.       all <- bmf %>%
  26.         summarize(
  27.           pop = "All registered nonprofits",
  28.           year = n()) 
  29.  
  30.       #calculate all public charities
  31.       pc <- bmf %>%  
  32.         filter((FNDNCD != "02" & FNDNCD!= "03" & FNDNCD != "04"), (SUBSECCD == "03")) %>%
  33.         summarize(
  34.           pop = "All 501(c)(3) public charities",
  35.           year = n())
  36.  
  37.       #calculate all active public charities
  38.       pcact <- bmf %>%  
  39.         filter((FNDNCD != "02" & FNDNCD!= "03" & FNDNCD != "04"), (SUBSECCD == "03")) %>%
  40.         filter(CFILER == "Y" & CZFILER =="N") %>%
  41.         summarize(
  42.           pop = "Reporting public charities",
  43.           year = n())
  44.  
  45.       #calculate all active supporting public charities
  46.       pcacts <- bmf %>%  
  47.         filter((FNDNCD != "02" & FNDNCD!= "03" & FNDNCD != "04"), (SUBSECCD == "03")) %>%
  48.         filter(CFILER == "Y" & CZFILER =="N") %>%
  49.         filter(str_sub(NTEECC,2,3) %in% c("11", "12")|
  50.                str_sub(NTEECC,1,2) %in% c("T2", "T3", "T6", "T7", "T9")) %>%
  51.         summarize(
  52.           pop = "Supporting public charities",
  53.           year = n())
  54.  
  55.       #calculate all active operating public charities
  56.       pcacto <- bmf %>%  
  57.         filter((FNDNCD != "02" & FNDNCD!= "03" & FNDNCD != "04"), (SUBSECCD == "03")) %>%
  58.         filter(CFILER == "Y" & CZFILER =="N") %>%
  59.         filter(!str_sub(NTEECC,2,3) %in% c("11", "12") &
  60.                  !str_sub(NTEECC,1,2) %in% c("T2", "T3", "T6", "T7", "T9")) %>%
  61.         summarize(
  62.           pop = "Operating public charities",
  63.           year = n())
  64.  
  65.       #calculate all non-reporting public charities
  66.       pcnact <- bmf %>%  
  67.         filter((FNDNCD != "02" & FNDNCD!= "03" & FNDNCD != "04"), (SUBSECCD == "03")) %>%
  68.         filter(CFILER == "N" |(CFILER =="Y" & CZFILER =="Y")) %>%
  69.         summarize(
  70.           pop = "Non-reporting, or with less than $50,000 in Gross Receipts",
  71.           year = n())
  72.  
  73.       #calculate all private foundations
  74.       pf <- bmf %>%  
  75.         filter((FNDNCD == "02" | FNDNCD== "03" | FNDNCD == "04"), (SUBSECCD == "03")) %>%
  76.         summarize(
  77.           pop = "All 501(c)(3) private foundations",
  78.           year = n())
  79.  
  80.       #calculate all non-operating foundations
  81.       pfno <- bmf %>%  
  82.         filter((FNDNCD == "04"), (SUBSECCD == "03")) %>%
  83.         summarize(
  84.           pop = "Private Grantmaking (Non-Operating) Foundations",
  85.           year = n())
  86.  
  87.       #calculate all operating foundations
  88.       pfo <- bmf %>%  
  89.         filter((FNDNCD == "02" | FNDNCD== "03"), (SUBSECCD == "03")) %>%
  90.         summarize(
  91.           pop = "Private Operating Foundations",
  92.           year = n())
  93.  
  94.       #calculate all other 501(c) roganizations
  95.       co <- bmf %>%  
  96.         filter((SUBSECCD != "03")) %>%
  97.         summarize(
  98.           pop = "All other 501(c) Nonprofit Organizations",
  99.           year = n())
  100.  
  101.       #calculate Civic leagues, social welfare orgs, etc.
  102.       co4 <- bmf %>%  
  103.         filter((SUBSECCD == "04")) %>%
  104.         summarize(
  105.           pop = "Civic leagues, social welfare orgs, etc.",
  106.           year = n())
  107.  
  108.       #calculate Fraternal beneficiary societies
  109.       co8 <- bmf %>%  
  110.         filter((SUBSECCD == "08")) %>%
  111.         summarize(
  112.           pop = "Fraternal beneficiary societies",
  113.           year = n())
  114.  
  115.       #calculate Business leagues, chambers of commerce, etc.
  116.       co6 <- bmf %>%  
  117.         filter((SUBSECCD == "06")) %>%
  118.         summarize(
  119.           pop = "Business leagues, chambers of commerce, etc.",
  120.           year = n())
  121.  
  122.       #calculate Labor, agricultural, horticultural orgs
  123.       co5 <- bmf %>%  
  124.         filter((SUBSECCD == "05")) %>%
  125.         summarize(
  126.           pop = "Labor, agricultural, horticultural orgs",
  127.           year = n())
  128.  
  129.       #calculate Social and recreational clubs
  130.       co7 <- bmf %>%  
  131.         filter((SUBSECCD == "07")) %>%
  132.         summarize(
  133.           pop = "Social and recreational clubs",
  134.           year = n())
  135.  
  136.       #calculate Post or organization of war veterans
  137.       co19 <- bmf %>%  
  138.         filter((SUBSECCD == "19")) %>%
  139.         summarize(
  140.           pop = "Post or organization of war veterans",
  141.           year = n())
  142.  
  143.       #calculate All Other Nonprofit Organizations
  144.       cooth <- bmf %>%  
  145.         filter((!SUBSECCD %in% c("03", "04", "08", "06", "05", "07","19"))) %>%
  146.         summarize(
  147.           pop = "Other Nonprofit Organizations",
  148.           year = n())
  149.  
  150.       #combine all data points
  151.       combined <- rbind(pc, pcact, pcacts, pcacto, pcnact, pf, pfno, pfo, co, co4, co8, co6, co5, co7, co19, cooth,all)
  152.  
  153.       #calculate percentages of all orgs
  154.       combined <- combined %>%
  155.         mutate(PctofAll = round((year/year[1])*100, digits=2))     
  156.  
  157.       #rename columns (with years)
  158.       colnames(combined) <- c("Nonprofit Type", 
  159.                               paste("# of Orgs:", as.character(year_of_int, sep = " ")),
  160.                               paste("% of All Orgs:", as.character(year_of_int, sep = " ")))
  161.  
  162.       #return combined file
  163.       return(combined)
  164.     }
  165.  
  166.     #run for each of 2 bmf years
  167.     bcomp1 <-bcomponent(bmf1, (datayear -10))
  168.     bcomp2 <-bcomponent(bmf2, datayear)
  169.  
  170.     #merge years
  171.     total <- bcomp1 %>%
  172.       left_join(bcomp2, by = "Nonprofit Type")
  173.  
  174.     #return combined file with both years
  175.     return(total)
  176.   }
  177.  
  178.   #run against year of interest:
  179.   btable<- byear(datayear)
  180.  
  181.   btable<- as.data.frame(btable)
  182.  
  183.   #calculate percentage change column
  184.   btable <- btable %>%
  185.     mutate( "Pct Change" = round(((btable[, 4] - btable[, 2])/(btable[, 2]))*100, digits=2))
  186.  
  187.   #add state name to final table
  188.   colnames(btable)[1] <- paste("Nonprofit Organizations in ", as.character(stname), sep ="")
  189.  
  190.  
  191.   #return final output
  192.   return(btable)
  193. }
  194.  
  195. #Generate output table
  196. kable(OverallT(as.integer(yearparam)), 
  197.       "html",
  198.       format.args = list(decimal.mark = '.', big.mark = ","),
  199.       align = "lccccc") %>%
  200.   kable_styling("hover", full_width = F) %>%
  201.   row_spec(17, bold = T, underline = T ) %>%
  202.   row_spec(c(1,6,9), bold = T) %>%
  203.   row_spec(c(3,4), italic = T) %>%
  204.   group_rows("Public Charities",1,5) %>%
  205.   group_rows("Private Foundations",6,8) %>%
  206.   group_rows("Other Organiations", 9,16) %>%
  207.   group_rows("Total", 17,17) %>%
  208.   #add_indent(c(3:6,8,9,11:17)) %>%
  209.   add_indent(c(3:4)) %>%
  210.   footnote(general = paste("Internal Revenue Service Business Master Files, Exempt Organizations (", as.integer(as.integer(yearparam)-9), ", ", as.integer(as.integer(yearparam)+1), ")", sep=""),
  211.            general_title = "Source ", 
  212.            title_format = "bold",
  213.            footnote_as_chunk = TRUE)
Nonprofit Organizations in Texas \# of Orgs: 2005 % of All Orgs: 2005 \# of Orgs: 2015 % of All Orgs: 2015 Pct Change
Public Charities
All 501(c)(3) public charities 57,206 100.00 80,840 100.00 41.31
Reporting public charities 18,545 32.42 22,952 28.39 23.76
Supporting public charities 2,521 4.41 3,331 4.12 32.13
Operating public charities 16,024 28.01 19,621 24.27 22.45
Non-reporting, or with less than $50,000 in Gross Receipts 38,661 67.58 57,888 71.61 49.73
Private Foundations
All 501(c)(3) private foundations 6,250 10.93 6,466 8.00 3.46
Private Grantmaking (Non-Operating) Foundations 5,982 10.46 6,027 7.46 0.75
Private Operating Foundations 268 0.47 439 0.54 63.81
Other Organiations
All other 501(c) Nonprofit Organizations 28,045 49.02 22,491 27.82 -19.80
Civic leagues, social welfare orgs, etc. 7,122 12.45 5,176 6.40 -27.32
Fraternal beneficiary societies 3,481 6.09 2,411 2.98 -30.74
Business leagues, chambers of commerce, etc. 5,480 9.58 5,094 6.30 -7.04
Labor, agricultural, horticultural orgs 2,391 4.18 1,641 2.03 -31.37
Social and recreational clubs 3,095 5.41 2,543 3.15 -17.84
Post or organization of war veterans 1,664 2.91 1,243 1.54 -25.30
Other Nonprofit Organizations 4,812 8.41 4,383 5.42 -8.92
Total
All registered nonprofits 91,501 159.95 109,797 135.82 20.00
Source Internal Revenue Service Business Master Files, Exempt Organizations (2006, 2016)
  1. #Create NTEE grouping categories
  2. arts <- c("A")
  3. highered <- c("B4", "B5")
  4. othered <- c("B")
  5. envanimals <- c("C", "D")
  6. hospitals <- c('E20','E21','E22','E23','E24','F31','E30','E31','E32')
  7. otherhlth <- c("E", "F", "G", "H")
  8. humanserv <- c("I", "J", "K", "L", "M", "N", "O", "P")
  9. intl <- c("Q")
  10. pubben <- c("R", "S", "T", "U", "V", "W", "Y", "Z")
  11. relig <- c("X")
  12.  
  13. #define function to join NTEE Master list and categorize organizations accordingly
  14. NTEEclassify <- function(dataset) {
  15.   #create NTEEGRP classifications
  16.   dataset$NTEEGRP <- "  "
  17.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% arts ] <- "Arts"
  18.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% othered ] <- "Other Education"
  19.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,2) %in% highered ] <- "Higher Education"
  20.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% envanimals] <- "Environment and Animals"
  21.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% otherhlth] <- "Other Health Care"
  22.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,3) %in% hospitals] <- "Hospitals and primary care facilities"
  23.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% humanserv] <- "Human Services"
  24.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% intl] <- "International"
  25.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% pubben] <- "Other Public and social benefit"
  26.   dataset$NTEEGRP[str_sub(dataset$NTEECC,1,1) %in% relig] <- "Religion related"
  27.   dataset$NTEEGRP[is.na(dataset$NTEECC)] <- "Other Public and social benefit"
  28.   return(dataset)
  29. }
  30.  
  31. BNorder<- c("Arts","Higher Education", "Other Education", "Environment and Animals",
  32.                "Hospitals and primary care facilities", "Other Health Care", "Human Services",
  33.                "International", "Other Public and social benefit", "Religion related")
  34.  
  35. #Classify most recent BMF by NTEE
  36. bmfNTEE <- NTEEclassify(bmf2015) %>%
  37.   filter(STATE == as.character(stateparam)) %>%
  38.   filter(((CTOTREV>50000)), (OUTNCCS != "OUT"), (FNDNCD != "02" & FNDNCD!= "03" & FNDNCD != "04")) %>%
  39.   group_by(NTEEGRP) %>%
  40.   summarize(Number_of_Orgs = n()) %>%
  41.   mutate(Numbers_PCT = round((Number_of_Orgs/sum(Number_of_Orgs)) *100, digits =1)) %>%
  42.   slice(match(BNorder, NTEEGRP))
  43.  
  44. #make sure plot will be ordered corretly
  45. bmfNTEE$NTEEGRPORDER <- factor(bmfNTEE$NTEEGRP, as.character(bmfNTEE$NTEEGRP))
  46.  
  47. #create figure (note: this is the only essential step, the rest is just styling!)
  48. NTEEFIG <- bmfNTEE %>%
  49.   ggplot(aes(x= NTEEGRPORDER,y= Numbers_PCT)) + 
  50.   geom_col() +
  51.     theme(axis.title.y = element_blank(),
  52.           axis.text.y = element_blank(),
  53.           axis.ticks.y = element_blank(),
  54.           axis.title.x = element_blank(),
  55.           panel.grid = element_blank()) +
  56.   #set bounds of plot
  57.   scale_y_continuous(expand = c(0, 0), limits= c(0,60)) +
  58.   # make sure labels will wrap text
  59.   scale_x_discrete(labels = c("Arts",
  60.                               "Higher\nEducation",
  61.                               "Other\nEducation", 
  62.                               "Environment\nand Animals", 
  63.                               "Hospitals",
  64.                                "Other Health\nCare", 
  65.                               "Human\nServices",
  66.                               "International",
  67.                               "Other  Pub.\n Benefit",
  68.                               "Religion\n Related")) +
  69.   #add text labels to columns
  70.   geom_text(aes(NTEEGRP, Numbers_PCT, label=formatC(Numbers_PCT, format = 'f', digits =1)),
  71.               vjust=-1, 
  72.               position = position_dodge(width=1),
  73.               size =3) 
  74.  
  75.   #Make figure title in Urban Institute style
  76.   Title <- textGrob("FIGURE 1", 
  77.                   x = unit(0, "npc"), 
  78.                   y = unit(0, "npc"),
  79.                   hjust = 0, 
  80.                   vjust = 0,
  81.                   gp = gpar(fontsize = 9, fontfamily = "Lato", col = "#1696d2"))
  82.  
  83.   #Make figure subtitle in Urban Institute Style
  84.   Subtitle <- textGrob(paste("Percent of reporting public charities in ", as.character(stname), " by subsector, ", as.integer(yearparam), sep =""), 
  85.                      x = unit(0, "npc"), 
  86.                      y = unit(0, "npc"),
  87.                      hjust = 0, 
  88.                      vjust = 0,
  89.                      gp = gpar(fontsize = 10, fontfamily = "Lato", fontface = "bold"))
  90.  
  91.   #Add Urban institute Caption
  92.   UrbCaption <- grobTree(
  93.     gp = gpar(fontsize = 8, hjust = 1), 
  94.     textGrob(label = "I N S T I T U T E", 
  95.              name = "caption1",
  96.              x = unit(1, "npc"),  
  97.              y = unit(0, "npc"),
  98.              hjust = 1, 
  99.              vjust = 0),
  100.     textGrob(label = "U R B A N  ", 
  101.              x = unit(1, "npc") - grobWidth("caption1") - unit(0.01, "lines"),         
  102.              y = unit(0, "npc"), 
  103.              hjust = 1, 
  104.              vjust = 0, 
  105.              gp = gpar(col = "#1696d2")))
  106.  
  107.   #Add sources in Urban Institute style
  108.   Sources <- grobTree(
  109.     gp = gpar(fontsize = 8, hjust = 0),
  110.     textGrob(label = paste("Internal Revenue Service Business Master Files, Exempt Organizations (", as.integer(as.integer(yearparam)+1), ")", sep=""), 
  111.              x = unit(0, "npc")+ grobWidth("sources1"),  
  112.              y = unit(0, "npc"),
  113.              hjust = 0, 
  114.              vjust = 0),
  115.     textGrob(label = "Source: ", 
  116.              name = "sources1",
  117.              x = unit(0, "npc") ,         
  118.              y = unit(0, "npc"), 
  119.              hjust = 0, 
  120.              vjust = 0,
  121.              gp = gpar(fontface = "bold")))
  122.  
  123.   #Combine elements
  124.   grid.arrange(Title, Subtitle, NTEEFIG, UrbCaption, Sources, ncol = 1, heights = c(2, 3, 30, 1, .5))