Is this month's key phrase "Medium-Intensity Residential"?
Recent sale prices and assessments by land use designation
Property transactions in Charlottesville: Hot market for parcels designated as "Middle Intensity" in Future Land Use Plan
I always make time to read Sean Tubbs's newsletter, and I was interested to see what he has to say about the new "Medium-Intensity Residential" land use designation adopted in last year's Comprehensive Plan. Sean noticed a number of properties with this designation, or located close to properties with this designation, that sold for high prices, some far above their most recent assessments. He wrote that
This month's key phrase is "Medium Intensity Residential".
and noted that
...properties with the Medium Intensity Residential designation are selling well over the 2022 assessment.
Sean writes that "I intend no analysis". Fair enough, but let's do some analysis! The city provides mostly current data on assessments, property transactions, and parcel details at its Open Data Portal, which I have been mirroring to a public dataset using Google BigQuery for ease of use. Let's dig into the claims in the blog post. As I read it, there are two key arguments that we can evaluate:
- Parcels with the Medium-Intensity Residential designation have been selling for over their official assessments
- The difference between sale prices and assessments is greater for Medium-Intensity Residential than for other designations
First, let's compare median sale prices, assessments, and the ratio between the two across land use designations. I'm looking at all sales in 2022 to begin with. Note that I'm excluding sales with a price of $0 and sales that included multiple parcels.
bq.query(
"""
select distinct
percentile_cont(sales.saleamount, 0.5) over (partition by flum.desig_oct) as saleamount,
percentile_cont(assessments.totalvalue, 0.5) over (partition by flum.desig_oct) as assessment,
percentile_cont(sales.saleamount / assessments.totalvalue, 0.5) over (partition by flum.desig_oct) as saleassessmentratio,
count(*) over (partition by flum.desig_oct) as count,
flum.desig_oct as designation,
from `cvilledata.cville_open_data.real_estate_sales` sales
join `cvilledata.cville_open_data.real_estate_all_assessments` assessments on sales.parcelnumb = assessments.parcelnumb and assessments.taxyear = 2022
join `cvilledata.cville_plans_together.flum_202110` flum on sales.parcelnumb = flum.parcelnumb
where sales.saledate >= '2022-01-01'
and sales.saleamount > 0
and sales.bookpage not in (
select
bookpage
from `cvilledata.cville_open_data.real_estate_sales`
where saledate >= '2022-01-01'
and saleamount > 0
group by bookpage
having count(*) > 1
)
and flum.desig_oct in (
'General Residential',
'Medium-Intensity Residential',
'High-Intensity Residential'
)
order by count desc
"""
).result().to_dataframe()
As Sean noted, Medium-Intensity Residential parcels are selling for over their assessments, with the median ratio of sale price to assessed value at 1.05, meaning that sales were typically about 5% over assessments. However, General Residential parcels had an even higher ratio of 1.13, with the median parcel selling for about 13% more than its assessed value. But Sean only considered March; let's use that same filter to make sure we're looking at the same parcels:
bq.query(
"""
select distinct
percentile_cont(sales.saleamount, 0.5) over (partition by flum.desig_oct) as saleamount,
percentile_cont(assessments.totalvalue, 0.5) over (partition by flum.desig_oct) as assessment,
percentile_cont(sales.saleamount / assessments.totalvalue, 0.5) over (partition by flum.desig_oct) as saleassessmentratio,
count(*) over (partition by flum.desig_oct) as count,
flum.desig_oct as designation,
from `cvilledata.cville_open_data.real_estate_sales` sales
join `cvilledata.cville_open_data.real_estate_all_assessments` assessments on sales.parcelnumb = assessments.parcelnumb and assessments.taxyear = 2022
join `cvilledata.cville_plans_together.flum_202110` flum on sales.parcelnumb = flum.parcelnumb
where sales.saledate >= '2022-03-01' and sales.saledate < '2022-04-01'
and sales.saleamount > 0
and sales.bookpage not in (
select
bookpage
from `cvilledata.cville_open_data.real_estate_sales`
where saledate >= '2022-03-01' and saledate < '2022-04-01'
and saleamount > 0
group by bookpage
having count(*) > 1
)
and flum.desig_oct in (
'General Residential',
'Medium-Intensity Residential',
'High-Intensity Residential'
)
order by count desc
"""
).result().to_dataframe()
Looking at March alone, Medium-Intensity Residential parcels had sale prices exceeding their assessments by about 12%, and General Residential parcels had prices exceeding their assessmens by about 18%.
Let's revisit the claims from above:
Parcels with the Medium-Intensity Residential designation have been selling for over their official assessments
This is consistent with the data! Medium-Intensity Residential parcels sold for about 5% more than assessments overall for 2022 and 12% in March alone. What about the next claim?
The difference between sale prices and assessments is greater for Medium-Intensity Residential than for other designations
This claim isn't supported here. While Medium-Intensity Residential parcels sold for over their assessment prices, this was also true for General Residential parcels, and it turns out that sale prices exceeeded assessments by an even higher proportion in General Residential. Sean wrote that
This month's key phrase is "Medium Intensity Residential".
But maybe the unusual thing about Medium-Intensity Residential is that the recent sale prices of these parcels have been lower, relative to assessments, than the General Residential category that makes up the bulk of the city's residential land.
I've tried to evaluate these claims in a bit more detail, but there are many limitations to this quick analysis. Maybe the Medium-Intensity Residential properties that have been sold this year are in different neighborhoods than the General Residential properties; maybe the city assesses properties differently by land use designation in a biased way. Maybe there was a pre-existing difference in land or property values across designations. Maybe correcting for these potential differences, or others that I haven't thought of, would support the claim that Medium-Intensity Residential properties are suddenly uniquely expensive. But at least so far, it appears that sale prices are higher than assessments citywide, and if anything this is more true of General Residential than Medium-Intensity Residential in recent months.
It's also worth pointing out that we don't have much data yet. The Comprehensive Plan was passed in December 2021, and only 23 parcels zoned Medium-Intensity Residential have sold in 2022 (not including multi-parcel transactions or homes built after 2020). Meanwhile, the zoning rewrite is just starting:we haven't actually changed the rules yet. It's interesting to look at the early data we have, but realistically, it's going to take years to draw conclusions with any confidence. Anyway, thanks to Sean for raising some interesting questions. If you're still reading, subscribe to his substack if you haven't already.
One last point: maybe this analysis has been skewed by a small number of unusual sales. Using medians rather than means should reduce the influence of outliers. And I've excluded sales that I don't think we should consider: specifically, properties that sold for $0 and properties that were sold as a package along with other properties. But maybe I missed something! So for completeness, here are the individual parcels that have sold in 2022, first Medium-Intensity Residential, then General Residential:
bq.query(
"""
select
sales.parcelnumb as parcelnumber,
sales.saleamount,
sales.saledate,
assessments.totalvalue,
sales.saleamount / assessments.totalvalue as saleassessmentratio,
sales.streetnumb,
sales.streetname,
sales.unit,
from `cvilledata.cville_open_data.real_estate_sales` sales
join `cvilledata.cville_open_data.real_estate_all_assessments` assessments on sales.parcelnumb = assessments.parcelnumb and assessments.taxyear = 2022
join `cvilledata.cville_plans_together.flum_202110` flum on sales.parcelnumb = flum.parcelnumb
where sales.saledate >= '2022-01-01'
and sales.saleamount > 0
and sales.bookpage not in (
select
bookpage
from `cvilledata.cville_open_data.real_estate_sales`
where saledate >= '2022-01-01'
and saleamount > 0
group by bookpage
having count(*) > 1
)
and flum.desig_oct = 'Medium-Intensity Residential'
order by sales.saledate desc
"""
).result().to_dataframe()
bq.query(
"""
select
sales.parcelnumb as parcelnumber,
sales.saleamount,
sales.saledate,
assessments.totalvalue,
sales.saleamount / assessments.totalvalue as saleassessmentratio,
sales.streetnumb,
sales.streetname,
sales.unit,
from `cvilledata.cville_open_data.real_estate_sales` sales
join `cvilledata.cville_open_data.real_estate_all_assessments` assessments on sales.parcelnumb = assessments.parcelnumb and assessments.taxyear = 2022
join `cvilledata.cville_plans_together.flum_202110` flum on sales.parcelnumb = flum.parcelnumb
where sales.saledate >= '2022-01-01'
and sales.saleamount > 0
and sales.bookpage not in (
select
bookpage
from `cvilledata.cville_open_data.real_estate_sales`
where saledate >= '2022-01-01'
and saleamount > 0
group by bookpage
having count(*) > 1
)
and flum.desig_oct = 'General Residential'
order by sales.saledate desc
"""
).result().to_dataframe()