Reputation: 135
I'm doing analysis on geographical data. I have data by state, and I'd like to group that by division and by region, as grouped by the Census Bureau. There is a hierarchy here: regions, divisions, and states, from large-to-small scale.
What I'd like to do is fill out a new dataframe that encodes that information. (I can then use that as a reference, and to clean the data.) I've tried a few ways around this but have been getting flummoxed. I appreciate any solutions.
Here's the list of divisions:
pacific <- c('WA', 'OR', 'CA', 'AK', 'HI')
mountain <- c('MT', 'ID', 'WY', 'NV', 'UT', 'CO', 'AZ', 'NM')
w.n.central <- c('ND', 'SD', 'NE', 'KS', 'MN', 'IA', 'MO')
w.s.central <- c('TX', 'OK', 'AR', 'LA')
e.n.central <- c('WI', 'MI', 'IL', 'IN', 'OH')
e.s.central <- c('KY', 'TN', 'MS', 'AL')
mid.atlantic <- c('NY', 'PA', 'NJ')
new.england <- c('VT', 'NH', 'MA', 'CT', 'RI', 'ME')
south.atlantic <- c('WV', 'MD', 'DE', 'DC', 'VA', 'NC', 'SC', 'GA', 'FL')
divisions <- c(pacific, mountain, w.n.central, w.s.central, e.n.central, e.s.central, mid.atlantic, south.atlantic, new.england)
And the list of regions:
northeast <- c(new.england, mid.atlantic)
midwest <- c(e.n.central, w.n.central)
south <- c(south.atlantic, e.s.central, w.s.central)
west <- c(mountain, pacific)
regions <- c(northeast, midwest, south, west)
Edit: I'd prefer the output to be a df of three columns (state, division, region).
Edit: because of the state dataset, this whole task ended up being unnecessary. instead i created the following:
data_frame(
state = state.abb,
state.name = state.name,
region = state.region,
division = state.division )
Upvotes: 1
Views: 62
Reputation: 21641
Using dplyr
:
library(dplyr)
chardiv <- c("pacific", "mountain", "w.n.central", "w.s.central",
"e.n.central", "e.s.central", "mid.atlantic",
"south.atlantic", "new.england")
dfdiv <- data.frame(state = unlist(mget(regions))) %>%
mutate(regions = gsub("[0-9]*$", "", rownames(.)))
dfstate = data.frame(state = unlist(mget(chardiv))) %>%
mutate(divisions = gsub("[0-9]*$", "", rownames(.)))
left_join(dfdiv, dfstate, by = "state")
You get:
#> head(df, 10L)
# state regions divisions
#1 VT northeast new.england
#2 NH northeast new.england
#3 MA northeast new.england
#4 CT northeast new.england
#5 RI northeast new.england
#6 ME northeast new.england
#7 NY northeast mid.atlantic
#8 PA northeast mid.atlantic
#9 NJ northeast mid.atlantic
#10 WI midwest e.n.central
Upvotes: 2
Reputation: 887861
May be this helps
st <- state.abb
lst <- mget(regions)
v1 <- unlist(lapply(names(lst), function(x) {
x1 <- lst[[x]]
setNames(rep(x, length(x1)),x1)}))
reg <- unname(v1[st])
divisions1 <- c('pacific', 'mountain', 'w.n.central', 'w.s.central',
'e.n.central', 'e.s.central', 'mid.atlantic', 'south.atlantic',
'new.england')
lst2 <- mget(divisions1)
v2 <- unlist(lapply(names(lst2), function(x) {
x1 <- lst2[[x]]
setNames(rep(x, length(x1)),x1)}))
div <- unname(v2[st])
dat <- data.frame(state=st, division=div, region=reg,
stringsAsFactors=FALSE)
head(dat,3)
# state division region
#1 AL e.s.central south
#2 AK pacific west
#3 AZ mountain west
Upvotes: 3