Data Center Opinion Project - Study 1

When people think about data centers and the resources that afford their development, they usually think in terms of four material resources: energy, land, water, and network infrastructure. In this research, we introduce an often overlooked but increasingly deterministic constraint: public sentiment.

We characterize public support as a true resource that affords - or constrains - data center construction in the same way that energy or water availability can. In study 1, the goal is to quantify the cost of public sentiment.

The goals are to address the following research questions: To what extent can public support be secured in the same way that a tech company would secure a water rights agreement? In other words, is public support for sale? And if so, how much does it cost?

Participants were recruited and paid through Verasight. Verasight gauranteed a nationally representative sample. Participants who were interested in taking the study were directed to our Qualtrics link, where they chose to consent or not before proceeding to the survey.

Sentiment

Overall, would you favor or oppose the construction of a new data center in your local area to support artificial intelligence, or AI, technology? [-2 = Strongly oppose, -1 = Somewhat oppose, 0 = No opinion, 1 = Somewhat favor, 2 = Strongly favor]

Data Center Density

How many data centers are currently within 5 miles of your home? [0 = None, 1 = One to two, 2 = More than two, 3 = I don’t know]

Free Response

You indicated that you ${q://QID70/ChoiceGroup/SelectedChoices} a tech company building a data center in your community. Write down some thoughts you had as you arrived at your judgment.

Reasons for support

You indicated that you ${q://QID70/ChoiceGroup/SelectedChoices} the construction of a data center in your community. To what extent did each of the following factors influence your judgment? [1 = Not at all influential; 5 = Extremely influential]

  • Quality of life for local residents
  • Local economic effects
  • The development of AI, or factors related to AI
  • Environmental effects
  • Effects on local resources

Price on Support

Displayed to participants who reported opposing or having no opinion.

Imagine a tech company is interested in building a data center in your community. They are willing to negotiate terms with the local residents. They are in talks with your local government to agree on a deal that would give all local residents a one-time tax rebate.

You indicated that you ${q://QID70/ChoiceGroup/SelectedChoices} ${e://Field/about}the construction of a data center in your local area to support AI. Under what conditions - in terms of a tax rebate - would you be willing to say that you support the construction of this data center in your community?

Indicate the dollar amount that the tech company should offer to local residents to gain your support.

Demographics

Demographic items were collected by Verasight and linked to the participant via verasight id:

  • gender
  • age
  • education
  • income
  • US census region
  • metropolitan area or not
  • race
  • hispanic
  • Political ID
  • political ID lean
  • voted in presidential election in 2024?
  • vote choice in 2024
show code
dcOpinion_study1 = merge(read.csv('study 1/dataCenterOpinion_01.csv'), readRDS('study 1/verasightDemogs.rds'), by='vsid') %>% 
  filter(dataCenterSentiment != "") %>% 
  mutate(dataCenterSentiment = factor(dataCenterSentiment, labels=c('Strongly oppose', 'Somewhat oppose', 'Have no opinion', 'Somewhat favor', 'Strongly favor')),
         dataCenterDensity = factor(dataCenterDensity, labels=c('None','1-2','More than 2', "I'm not sure"))) %>% 
  mutate(dataCenterDensity_collapsed = factor(ifelse(dataCenterDensity == "I'm not sure", 1, dataCenterDensity), labels=c('None','1-2', 'More than 2')),
         priceForSupport_withoutStrongOpposerZeroes = ifelse(dataCenterSentiment == "Strongly oppose" & priceForSupport <1, NA, priceForSupport)) %>% 
  mutate(priceForSupport_withSupporters = ifelse(dataCenterSentiment == "Somewhat favor" | dataCenterSentiment =="Strongly favor", 0, priceForSupport),
         priceForSupport_withSupporters = ifelse(dataCenterSentiment == "Strongly oppose" & priceForSupport <1, NA, priceForSupport_withSupporters),
         priceForSupport_binned = factor(ifelse(priceForSupport_withoutStrongOpposerZeroes <1, "$0", 
                                         ifelse(priceForSupport_withoutStrongOpposerZeroes > 0 & priceForSupport_withoutStrongOpposerZeroes < 1001, "$1K or less",
                                                ifelse(priceForSupport_withoutStrongOpposerZeroes >1000 & priceForSupport_withoutStrongOpposerZeroes <10001, "More than $1K",
                                                       ifelse(priceForSupport_withoutStrongOpposerZeroes >10000 & priceForSupport_withoutStrongOpposerZeroes <50001, "More than $10K",
                                                              ifelse(priceForSupport_withoutStrongOpposerZeroes >50000 & priceForSupport_withoutStrongOpposerZeroes <100001, "More than $50K", 
                                                              ifelse(priceForSupport_withoutStrongOpposerZeroes >100000 & priceForSupport_withoutStrongOpposerZeroes <1000001, 'More than $100K',
                                                                     ifelse(priceForSupport_withoutStrongOpposerZeroes >1000000 & priceForSupport_withoutStrongOpposerZeroes <1000000001, 'More than $1M', "More than $1B"))))))), levels=c(NA, '$0','$1K or less','More than $1K', 'More than $10K','More than $50K','More than $100K','More than $1M','More than $1B')),
         income_buckets = ifelse(as.numeric(income) < 4, "lower income",
                                                    ifelse(as.numeric(income) ==4 | as.numeric(income) ==5, "middle income",
                                                           ifelse(as.numeric(income) >5, "upper income", NA))),
         reasonsTally = rowSums(pick("support_qualityOfLife", "support_localEconomy", "support_AIdev", "support_environment", "support_naturalResources") > 1, na.rm = TRUE)) %>% 
         mutate(reasonsTally_fct = factor(ifelse(reasonsTally <2, "1 or less", reasonsTally)))

We collected a total of 3234 responses. Note that responding to the “price for support” option was encouraged but not required, so some were left NA.

Overall sentiment to a local data center build

show code
nice_table(dcOpinion_study1 %>% group_by(dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100))

dataCenterSentiment

n

percent

Strongly oppose

1,448

44.77

Somewhat oppose

681

21.06

Have no opinion

513

15.86

Somewhat favor

463

14.32

Strongly favor

129

3.99

show code
overallSentiment_plot = dcOpinion_study1 %>% group_by(dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% mutate(dataCenterSentiment = fct_rev(dataCenterSentiment)) %>% 
  ggplot(aes(x = .5, y=percent, fill = dataCenterSentiment))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#232D4B','#C8CBD2','#FDDA24','#F9DCBF','#E57200'))+
  coord_flip()

overallSentiment_plot

show code
# ggsave(overallSentiment_plot, filename='study 1/overallSentiment_plot.png', dpi = 300)

Price for support

Participants who did not support a local data center build were asked to register their required price to gain their support. In the following analyses, participants who supported a local data center build are logged as “$0” for this variable.

In addition, there were a decent amount of participants who reported strong opposition to a local data center build, but registered “$0” as the price for their support. I interpreted these to mean “there is no amount of money that would buy my support.” Accordingly, I set those data points to NA

Raw results

Raw results can’t be plotted bc the distribution is too big:

  • mean = 3.4662045^{304}
  • min = 0
  • max = 10^{308}
  • median = 5000

Somebody registered “$-1” and they strongly opposed a local data center build. Probably should be interpreted as “nothing will buy my support”? Set to NA

Cutoff: billion

174 participants registered price tags higher than $1 billion. Excluding them yields 2711 data points.

show code
nice_table(dcOpinion_study1 %>% filter(priceForSupport_withSupporters<1000000001) %>% summarise(mean = mean(priceForSupport_withSupporters/1000), sd = sd(priceForSupport_withSupporters)/1000, median=median(priceForSupport_withSupporters)/1000, min = min(priceForSupport_withSupporters), max = max(priceForSupport_withSupporters)/1000), title = "Payment required for support, in thousands. (minimum reported in raw)")
ggplot(subset(dcOpinion_study1,priceForSupport_withSupporters<1000000001 &!is.na(priceForSupport_withSupporters)), aes(x=priceForSupport_withSupporters/1000))+
  geom_density(fill="#00bfc4", alpha=0.4)+
  geom_vline(aes(xintercept=mean(priceForSupport_withSupporters)/1000),color="#00bfc4", linetype="dashed", linewidth=0.5)+
  labs(x="Payment required for support, in thousands.", title="Cutoff: $1 billion")+
  theme_classic()

Payment required for support, in thousands. (minimum reported in raw)

mean

sd

median

min

max

23,966.79

144,119.32

5.00

0.00

1,000,000.00

Cutoff: million

401 participants registered price tags higher than $1 million. Excluding them yields 2484 data points.

show code
nice_table(dcOpinion_study1 %>% filter(priceForSupport_withSupporters<1000001) %>% summarise(mean = mean(priceForSupport_withSupporters/1000), sd = sd(priceForSupport_withSupporters)/1000, median=median(priceForSupport_withSupporters)/1000, min = min(priceForSupport_withSupporters), max = max(priceForSupport_withSupporters)/1000), title = "Payment required for support, in thousands. (minimum reported in raw)")
ggplot(subset(dcOpinion_study1,priceForSupport_withSupporters<1000001 &!is.na(priceForSupport_withSupporters)), aes(x=priceForSupport_withSupporters/1000))+
  geom_density(fill="#00bfc4", alpha=0.4)+
  geom_vline(aes(xintercept=mean(priceForSupport_withSupporters)/1000),color="#00bfc4", linetype="dashed", linewidth=0.5)+
  labs(x="Payment required for support, in thousands.", title="Cutoff: $1 million")+
  theme_classic()

Payment required for support, in thousands. (minimum reported in raw)

mean

sd

median

min

max

109.96

281.67

3.00

0.00

1,000.00

further visualizations

Among non-supporters (opposers and no opinions):

show code
nice_table(dcOpinion_study1 %>% filter(dataCenterSentiment != "Somewhat favor" & dataCenterSentiment != "Strongly favor" &!is.na(priceForSupport_binned)) %>% group_by(priceForSupport_binned) %>% tally() %>% mutate(percent = n/sum(n)*100))
horizontalDotPlot = ggplot(dcOpinion_study1, aes(x = 1, y=priceForSupport_withoutStrongOpposerZeroes))+
  geom_count(position=position_jitter(), alpha=0.65, color='#E57200')+
  scale_y_continuous(breaks = c(10000, 50000, 100000, 250000, 500000, 1000000), limits=c(0,1000001))+
  coord_flip()+
  theme_classic(base_size=13)+
  theme(axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        axis.line.y = element_blank())

#ggsave(horizontalDotPlot, filename='study 1/horizontalDotPlot.svg', dpi = 300, width=8, height=2)

horizontalDotPlot
percentBinsTable = data.frame("price" = c('$1K or less', '$10K or less', '$50K or less', '$100K or less', '$1M or less'),
                                "percentage" = c(22.72, 50.63, 62.14, 69.28, 82.41)) %>% 
  mutate(price = factor(price, levels=c('$1M or less','$100K or less', '$50K or less', '$10K or less', '$1K or less')))

percentBins_plot =ggplot(percentBinsTable, aes(x = price, y=percentage, fill = price))+
  geom_bar(stat = "identity", position=position_dodge(), color='white') +
  scale_y_continuous(breaks=c(0,50,100), limits=c(0,100))+
  theme_classic(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='none')+
  scale_fill_manual(values=c('#E57200','#ec9049','#f1ac79','#f7c7a7','#F9DCBF'))+
  coord_flip()

# ggsave(percentBins_plot, filename='study 1/percentBinsPlot.png', dpi = 300, width = 8, height = 6)

percentBins_plot

priceForSupport_binned

n

percent

$0

161

7.02

$1K or less

360

15.70

More than $1K

640

27.91

More than $10K

264

11.51

More than $50K

166

7.24

More than $100K

301

13.13

More than $1M

227

9.90

More than $1B

174

7.59

Sentiment by demographics

current local data center density

show code
# nice_table(dcOpinion_study1 %>% group_by(dataCenterDensity_collapsed, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100))

dcOpinion_study1 %>% group_by(dataCenterDensity_collapsed, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% filter(!is.na(dataCenterDensity_collapsed)) %>% mutate(dataCenterSentiment = fct_rev(dataCenterSentiment)) %>% 
  ggplot(aes(x = .5, y=percent, fill = dataCenterSentiment))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#232D4B','#C8CBD2','#FDDA24','#F9DCBF','#E57200'))+
  coord_flip()+
  facet_wrap(~dataCenterDensity_collapsed, ncol = 1)

political orientation

show code
# nice_table(dcOpinion_study1 %>% group_by(pid_base, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100))

sentimentByPoliticalID_plot = dcOpinion_study1 %>% group_by(pid_base, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% filter(pid_base %in% c('Democrat', 'Republican','Independent')) %>% mutate(dataCenterSentiment = fct_rev(dataCenterSentiment)) %>% 
  ggplot(aes(x = .5, y=percent, fill = dataCenterSentiment))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#232D4B','#C8CBD2','#FDDA24','#F9DCBF','#E57200'))+
  coord_flip()+
  facet_wrap(~pid_base, ncol = 1)

# ggsave(sentimentByPoliticalID_plot, filename='study 1/sentimentByPoliticalID_plot.png', dpi = 300, width=12, height = 12)
  
sentimentByPoliticalID_plot

density

age

income

show code
# nice_table(dcOpinion_study1 %>% group_by(income, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100))

dcOpinion_study1 %>% filter(!is.na(income)) %>%  group_by(income, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% mutate(dataCenterSentiment = fct_rev(dataCenterSentiment)) %>% 
  ggplot(aes(x = .5, y=percent, fill = dataCenterSentiment))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#232D4B','#C8CBD2','#FDDA24','#F9DCBF','#E57200'))+
  coord_flip()+
  facet_wrap(~income)

show code
income_price_plot = ggplot(subset(dcOpinion_study1, !is.na(income_buckets)), aes(x = income_buckets, y=as.numeric(priceForSupport_withoutStrongOpposerZeroes)))+
  geom_count(position=position_jitter(), alpha=0.25, aes(color=income_buckets))+
  scale_y_continuous(breaks = c(10000, 50000, 100000, 250000, 500000, 1000000), limits=c(0,500000))+
  theme_classic(base_size=13)+
  scale_color_manual(values=c('#62BB46','#ef3f6b','#25CAD3'))

ggsave(income_price_plot, filename='income_price_plot.png', dpi = 600, width=6, height = 4)

region

show code
dcOpinion_study1 %>% filter(!is.na(region)) %>%  group_by(region, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% mutate(dataCenterSentiment = fct_rev(dataCenterSentiment)) %>% 
  ggplot(aes(x = .5, y=percent, fill = dataCenterSentiment))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#232D4B','#C8CBD2','#FDDA24','#F9DCBF','#E57200'))+
  coord_flip()+
  facet_wrap(~region)

age

show code
# nice_table(dcOpinion_study1 %>% filter(!is.na(age_group4)) %>%  group_by(age_group4, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100))

sentimentByAge_plot = dcOpinion_study1 %>% filter(!is.na(age_group4)) %>%  group_by(age_group4, dataCenterSentiment) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% mutate(dataCenterSentiment = fct_rev(dataCenterSentiment)) %>% 
  ggplot(aes(x = .5, y=percent, fill = dataCenterSentiment))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#232D4B','#C8CBD2','#FDDA24','#F9DCBF','#E57200'))+
  coord_flip()+
  facet_wrap(~age_group4, ncol=1)

#ggsave(sentimentByAge_plot, filename='study 1/sentimentByAge_plot.png', dpi = 300, width=12, height = 12)

Reasons for support/opposition

show code
nice_table(dcOpinion_study1 %>% filter(dataCenterSentiment=='Strongly oppose' | dataCenterSentiment=='Somewhat oppose') %>% 
             group_by(reasonsTally_fct) %>% tally() %>% mutate(percent = n/sum(n)*100), title='opposers')

opposers

reasonsTally_fct

n

percent

1 or less

50

2.35

2

14

0.66

3

83

3.90

4

352

16.53

5

1,630

76.56

show code
opposers_reasons_plot = dcOpinion_study1 %>% filter(dataCenterSentiment=='Strongly oppose' | dataCenterSentiment=='Somewhat oppose') %>% 
  group_by(reasonsTally_fct) %>% 
  tally() %>% mutate(percent = n/sum(n)*100) %>% 
  ggplot(aes(x = .5, y=percent, fill = reasonsTally_fct))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#009fdf','#33b2e5','#66c5ec','#99d9f2','#ccecf9'))+
  coord_flip()

opposers_reasons_plot

show code
#ggsave(opposers_reasons_plot, filename='study 1/opposers_reasons_plot.png', dpi = 300, width=12, height = 6)

nice_table(dcOpinion_study1 %>% filter(dataCenterSentiment=='Strongly favor' | dataCenterSentiment=='Somewhat favor') %>% 
             group_by(reasonsTally_fct) %>% tally() %>% mutate(percent = n/sum(n)*100), title='supporters')

supporters

reasonsTally_fct

n

percent

1 or less

9

1.52

2

23

3.89

3

41

6.93

4

72

12.16

5

447

75.51

show code
supporters_reasons_plot = dcOpinion_study1 %>% filter(dataCenterSentiment=='Strongly favor' | dataCenterSentiment=='Somewhat favor') %>% 
  group_by(reasonsTally_fct) %>% 
  tally() %>% mutate(percent = n/sum(n)*100) %>% 
  ggplot(aes(x = .5, y=percent, fill = reasonsTally_fct))+
  geom_bar(stat = "identity", color='white') +
  theme_void(base_size=15)+
  labs(fill="", x='') +
  theme(legend.position='top')+
  scale_fill_manual(values=c('#62bb46','#81c96b','#a1d690','#c0e4b5','#e0f1da'))+
  coord_flip()

supporters_reasons_plot

show code
# ggsave(supporters_reasons_plot, filename='study 1/supporters_reasons_plot.png', dpi = 300, width=12, height = 6)

supporters_reasonsLollipop = dcOpinion_study1 %>% filter(dataCenterSentiment=='Strongly favor' | dataCenterSentiment=='Somewhat favor') %>% 
  group_by(reasonsTally_fct) %>% 
  tally() %>% mutate(percent = n/sum(n)*100) %>% 
  ggplot(aes(x=reasonsTally_fct, y=percent)) +
  geom_segment(
    aes(x=reasonsTally_fct, xend=reasonsTally_fct, y=0, yend=percent), linewidth=0.75) +
  geom_point(
    color="#009fdf", size= 4)+
  theme_classic() +
  coord_flip() +
  ylim(c(0,80))

supporters_reasonsLollipop

show code
# ggsave(supporters_reasonsLollipop, filename='study 1/supporters_reasonsLollipop.png', dpi = 500, width=4, height = 3)

opposer_reasonsLollipop = dcOpinion_study1 %>% filter(dataCenterSentiment=='Strongly oppose' | dataCenterSentiment=='Somewhat oppose') %>% 
  group_by(reasonsTally_fct) %>% 
  tally() %>% mutate(percent = n/sum(n)*100) %>% 
  ggplot(aes(x=reasonsTally_fct, y=percent)) +
  geom_segment(
    aes(x=reasonsTally_fct, xend=reasonsTally_fct, y=0, yend=percent), linewidth=0.75) +
  geom_point(
    color="#62bb46", size= 4)+
  theme_classic() +
  coord_flip() +
  ylim(c(0,80))

opposer_reasonsLollipop

show code
# ggsave(opposer_reasonsLollipop, filename='study 1/opposer_reasonsLollipop.png', dpi = 500, width=4, height = 3)

free responses

Free response word counts, grouped by supporters and non supporters.

Supporters:

show code
library('ggwordcloud'); library('stringr'); library('tidytext')

freeResponse_wordCounts_supporters = dcOpinion_study1 %>%
  filter(dataCenterSentiment == 'Strongly favor' | dataCenterSentiment =='Somewhat favor') %>% 
  select(support_freeResponse) %>% 
  unnest_tokens(word, support_freeResponse) %>%
  anti_join(stop_words) %>%
  count(word, sort = TRUE)
Joining with `by = join_by(word)`
show code
head(freeResponse_wordCounts_supporters)
       word   n
1      data 199
2      jobs 162
3        ai 131
4   centers 109
5    center  83
6 community  71
show code
# data, jobs, ai, centers, center, community, local, future, bring, people, water

Opposers:

show code
freeResponse_wordCounts_opposers = dcOpinion_study1 %>%
  filter(dataCenterSentiment == 'Strongly oppose' | dataCenterSentiment =='Somewhat oppose') %>% 
  select(support_freeResponse) %>% 
  unnest_tokens(word, support_freeResponse) %>%
  anti_join(stop_words) %>%
  count(word, sort = TRUE)
Joining with `by = join_by(word)`
show code
head(freeResponse_wordCounts_opposers)
         word   n
1        data 783
2       water 767
3     centers 633
4          ai 376
5   resources 275
6 environment 260
show code
# data water centers ai resources environment energy electricity center people power community jobs

free response by political orientation

Free response word counts by

show code
dcOpinion_study1 %>%
  filter((dataCenterSentiment == 'Strongly oppose' | dataCenterSentiment =='Somewhat oppose') & pid_base =='Democrat') %>% 
  select(support_freeResponse) %>% 
  unnest_tokens(word, support_freeResponse) %>%
  anti_join(stop_words) %>%
  count(word, sort = TRUE) %>% 
  slice(1:7)#water: 335; environment: 146; resources: 142; electricity: 119; energy: 96; power: 83; environmental: 66
Joining with `by = join_by(word)`
         word   n
1        data 384
2       water 335
3     centers 321
4          ai 172
5 environment 146
6   resources 142
7 electricity 119
show code
#921 total democrats in opposition with free response answers. 

dcOpinion_study1 %>%
  filter((dataCenterSentiment == 'Strongly oppose' | dataCenterSentiment =='Somewhat oppose') & pid_base =='Republican') %>% 
  select(support_freeResponse) %>% 
  unnest_tokens(word, support_freeResponse) %>%
  anti_join(stop_words) %>%
  count(word, sort = TRUE)%>% 
  slice(1:7) #water: 162; energy: 55; power: 47; resources: 44; environment: 36
Joining with `by = join_by(word)`
     word   n
1   water 162
2    data 149
3 centers 107
4      ai  70
5  energy  55
6  center  52
7   power  47
show code
#489 republicans in opposition with free response answers

## The reason why data center opinions are bipartisan is because environmental concerns look different IMBY than global climate change because it's more concrete than abstract 

words <- c("water", "resources", "environment", "jobs", "community")

word_counts <- dcOpinion_study1 %>%
    filter(pid_base != 'Independent' & !is.na(pid_base) & support_freeResponse!="" & as.numeric(dataCenterSentiment) < 3) %>% 
    group_by(pid_base) %>%
  summarise(
    water = mean(str_detect(str_to_lower(support_freeResponse), "water")) * 100,
    resources = mean(str_detect(str_to_lower(support_freeResponse), "resources")) * 100,
    power = mean(str_detect(str_to_lower(support_freeResponse), "energy|power|electric")) * 100,
    environment = mean(str_detect(str_to_lower(support_freeResponse), "environment")) * 100,
    nature = mean(str_detect(str_to_lower(support_freeResponse), "natur")) * 100,
    pollution = mean(str_detect(str_to_lower(support_freeResponse), "pollut")) * 100,
    noise = mean(str_detect(str_to_lower(support_freeResponse), "nois")) * 100,
    jobs = mean(str_detect(str_to_lower(support_freeResponse), "jobs")) * 100) 


wordRadar_plot = word_counts %>%
  filter(pid_base !='Other or none') %>% 
  ggradar(
    grid.max = 35,
    group.colours = c("#2B6CB0","#E05B30"),
    background.circle.colour = "white",
    gridline.mid.colour = "white",
    label.gridline.min = FALSE,
  label.gridline.mid = FALSE,
  label.gridline.max = FALSE,
  plot.legend=FALSE,
  fill = TRUE,
  axis.line.colour = "grey95",
  group.point.size = .1,
  group.line.width=1,
  gridline.max.colour = "white",
  gridline.min.colour = "white")

# ggsave(wordRadar_plot, filename='study 1/wordRadar_plot.png', dpi = 500, width=5, height = 4)

Claude simulated 300 responses to the following question:

And included demographic information for respondents.

show code
simulatedData = read.csv('datacenter_rebate_simulation.csv')

nice_table(simulatedData %>% group_by(ethnicity) %>% count())
nice_table(simulatedData %>% group_by(age_bracket) %>% count())
nice_table(simulatedData %>% group_by(gender) %>% count())
nice_table(simulatedData %>% group_by(income_bracket) %>% count())

ethnicity

n

Asian or Asian American

21

Black or African American

43

Hispanic or Latino

50

Other/Multiracial

17

White (non-Hispanic)

169

age_bracket

n

18-29

57

30-44

71

45-59

66

60-74

72

75+

34

gender

n

Man

155

Non-binary/other

3

Woman

142

income_bracket

n

$100k–$150k

43

$30k–$60k

67

$60k–$100k

96

Over $150k

54

Under $30k

40

Claude simulated prior approval/opposition to a data center being built in the local area.

show code
simulatedData %>% group_by(prior_attitude_numeric) %>% tally() %>% mutate(percent = n/sum(n)*100) %>% 
  ggplot(aes(x = prior_attitude_numeric, y=percent, fill = as.factor(prior_attitude_numeric)))+
  geom_bar(stat = "identity", position = "dodge") +
  theme_minimal()+
  labs(fill="")

The simulated data very much missed the mark here, likely because public sentiment about data centers is so quickly changing.

And finally, the simulated requested tax rebate amounts:

show code
gghistogram(subset(simulatedData, rebate_condition== 'one-time'), x = 'wta_amount')+labs(title='One Time Payment')
gghistogram(subset(simulatedData, rebate_condition== 'yearly'), x = 'wta_amount')+labs(title='Yearly Payments')

Note that Claude implemented a randomly assigned condition to either report a yearly or a one-time payment requirement.

Claude noted that the following likely issues:

  • Respondents will report $0 or refuse to answer if there is no amount of money that is sufficient

  • Respondents will anchor to the $1200 stimulus payment checks