areal interpolation weights issue

Hi all,

I am trying to allocate census data based on the block group level into school attendance zones. In using this code, the weights are based on the area of the block group covered by any attendance zone. However, at the edges of the map, there are places where block groups are partly in one school zone and partly not covered by any school zone. For example, a block group might be 20% in School Zone A, 30% in School Zone B, but 50% not covered by any school zone. The code above does not account for this missing 50% and therefore allocates all the residents of that block group into school zones A and B, rather than only 20% and 30% respectively.

Can anyone help me with adjusting this code such that the denominator for the block group weights reflects the total area of the block group?

schoolzones %>% aw_intersect(censusbgs, areaVar = "area") %>% 
    aw_total(censusbgs, id = FIPS, areaVar = "area", 
        totalVar = "totalArea", type = "extensive", weight = "sum") %>% 
    aw_weight(areaVar = "area", totalVar = "totalArea", areaWeight = "bg_weight") 

Created on 2022-09-12 with reprex v2.0.2

@chris.prener

Maybe you should adjust the proportions when doing the allocation, then calculating on those?

Otherwise, it is pretty much impossible to help without a reproducible example:

Hi William,

Thanks for the prompt reply. I don't know how to read-in a reproducible example with GIS data, so I created a tiny version of the data and uploaded it to github: GitHub - ellyfield/Help

I assume the issue happens somewhere in the "aw_total" line, but I can't figure out how to get it to consider the entire block group as the total area, rather than just the segments of the block group covered by the zones.

Thanks for any help you can provide!

Hi, I couldn't get your files to load.

Perhaps the information that you're after is in here though:
Areal Weighted Interpolation • areal (chris-prener.github.io)

The area weighting is not an overly difficult calculation; you could do it directly - meaning via actually calculating the areas using low level sf::st_area() and sf::st_intersection(), not relying on a package that introduces its own set of assumptions.

For a possible approach consider this example Spatial Aggregation · Jindra Lacko

Note that you will have to do several steps:

  • assign id's to block groups
  • calculate total area of block groups
  • assign id's to school zones
  • run sf::st_intersection() of blocks (with id's and known area totals + total population) over school zones (with their own id's)
  • you will get object of intersections with both id's and original block area as a number
  • you calculate population of the intersection as a % of the original population in relation of the area of intersection over original area
  • final step is aggregating the population according to school zone id

It may sound kinda difficult, but in reality is just a special case of cross multiplication. I hope the code I linked helps.

1 Like

Thank you both! I think I've figured it out now, had some underlying data issues that were adding to the problem, but I've figured it out with these resources.

Thanks both!

2 Likes

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.