%>%
df as_survey_design(ids = c_psu,
strata = c_strata,
weights = c_indinub_xw) %>%
group_by(gscorep_qnt, etap_fam_qnt, etap_big5_qnt) %>%
summarise(cmean = survey_mean(college, vartype = 'ci')) %>%
ggplot(aes(x = gscorep_qnt,
y = cmean, ymin = cmean_low, ymax = cmean_upp,
colour = factor(etap_fam_qnt),
group = factor(etap_fam_qnt))) +
geom_pointrange() +
geom_line() +
facet_wrap(~ etap_big5_qnt, scales = 'fixed',
labeller = as_labeller(function(x)
paste('Big5 score quintile =', x))) +
labs(x = 'IQ score quintile', y = 'Share with college degree',
colour = 'Fam score quintile') +
scale_colour_viridis_d() +
theme_minimal() +
theme(legend.position = 'bottom',
axis.line = element_line())
Intelligence and Income
Introduction
Cognitive and noncognitive skills and family background are important determinants of education
Policies can change the relative importance of these factors (Ichino, Rustichini, and Zanella 2022)
Growing evidence on interplay between genes and environment (Rustichini et al. 2023)
Contributions
Determinants of education: Heckman, Stixrud, and Urzua (2006), Almlund et al. (2011), Björklund and Salvanes (2011), Ichino, Rustichini, and Zanella (2022)
Genes and environment in education: Rustichini et al. (2023)
UK Household Longitudinal Study (2009-)
Working sample: 22 881 individuals
college: ever had HE degree as highest qualification
predicted discounted present value of earnings
cognitive test scores , Big 5 personality scores
parental background: education and employment status
METADAC
Genotyped subsample: 3 413 individuals
- polygenic score (PGS) of fluid intelligence (Savage et al. 2018)
College and individual characteristics
Probability of college
<- read_dta('tab1.dta')
tab1 <- tab1 %>% rename(std.error = std_err)
tab1 <- tab1 %>%
tab1 mutate(p.value = pnorm(abs(estimate) / std.error,
lower.tail = FALSE))
<- tab1 %>%
tab1_list nest(.by = c(cohort, spec)) %>%
mutate(cohort = str_extract(cohort, '(?<=19)[:digit:]{2}')) %>%
unite('id', spec, cohort, sep = '') %>%
deframe()
<- list(tidy = tab1_list$ols50,
tab1_ols50 glance = tab1_list$ols50 %>% distinct(N))
<- list(tidy = tab1_list$logme50,
tab1_lme50 glance = tab1_list$logme50 %>% distinct(N))
<- list(tidy = tab1_list$ols65,
tab1_ols65 glance = tab1_list$ols65 %>% distinct(N))
<- list(tidy = tab1_list$ols65,
tab1_lme65 glance = tab1_list$ols65 %>% distinct(N))
<- list(tidy = tab1_list$ols80,
tab1_ols80 glance = tab1_list$ols80 %>% distinct(N))
<- list(tidy = tab1_list$ols80,
tab1_lme80 glance = tab1_list$ols80 %>% distinct(N))
class(tab1_ols50) <- 'modelsummary_list'
class(tab1_lme50) <- 'modelsummary_list'
class(tab1_ols65) <- 'modelsummary_list'
class(tab1_lme65) <- 'modelsummary_list'
class(tab1_ols80) <- 'modelsummary_list'
class(tab1_lme80) <- 'modelsummary_list'
modelsummary(list(OLS = tab1_ols50,
'Logit ME' = tab1_lme50,
OLS = tab1_ols65,
'Logit ME' = tab1_lme65,
OLS = tab1_ols80,
'Logit ME' = tab1_lme80),
coef_map = c(g_score_std = 'IQ score',
eta_fam_score_std = 'Fam score',
eta_big5_score_std = 'Big5 score'),
gof_map = list(list(raw = 'N', clean = 'Obs.',
fmt = function(x) format(x,
big.mark = ' '))),
stars = c('*' = .05, '**' = .01, '***' = 0.001)) %>%
group_tt(j = list('Born in 1950-64' = 2:3,
'Born in 1965-79' = 4:5,
'Born in 1980-94' = 6:7))
Born in 1950-64 | Born in 1965-79 | Born in 1980-94 | ||||
---|---|---|---|---|---|---|
OLS | Logit ME | OLS | Logit ME | OLS | Logit ME | |
* p < 0.05, ** p < 0.01, *** p < 0.001 | ||||||
IQ score | 0.137*** | 0.152*** | 0.151*** | 0.151*** | 0.130*** | 0.130*** |
(0.005) | (0.007) | (0.005) | (0.005) | (0.006) | (0.006) | |
Fam score | 0.050*** | 0.054*** | 0.077*** | 0.077*** | 0.074*** | 0.074*** |
(0.005) | (0.008) | (0.006) | (0.006) | (0.006) | (0.006) | |
Big5 score | 0.006 | 0.015** | 0.010* | 0.010* | 0.014* | 0.014* |
(0.006) | (0.006) | (0.006) | (0.006) | (0.006) | (0.006) | |
Obs. | 9 539 | 9 539 | 10 586 | 10 586 | 8 409 | 8 409 |
SEM of college and wages
<- read_dta('tab3.dta')
tab3 <- tab3 %>% rename(std.error = std_err)
tab3 <- tab3 %>%
tab3 mutate(p.value = pnorm(abs(estimate) / std.error,
lower.tail = FALSE))
<- tab3 %>%
tab3_list nest(.by = c(cohort, depvar)) %>%
mutate(cohort = str_extract(cohort, '(?<=19)[:digit:]{2}')) %>%
unite('id', depvar, cohort, sep = '') %>%
deframe()
<- list(tidy = tab3_list$wage4550,
tab3_wage4550 glance = tab3_list$wage4550 %>% distinct(N))
<- list(tidy = tab3_list$college50,
tab3_college50 glance = tab3_list$college50 %>% distinct(N))
<- list(tidy = tab3_list$wage4565,
tab3_wage4565 glance = tab3_list$wage4565 %>% distinct(N))
<- list(tidy = tab3_list$college65,
tab3_college65 glance = tab3_list$college65 %>% distinct(N))
<- list(tidy = tab3_list$wage4580,
tab3_wage4580 glance = tab3_list$wage4580 %>% distinct(N))
<- list(tidy = tab3_list$college80,
tab3_college80 glance = tab3_list$college80 %>% distinct(N))
class(tab3_wage4550) <- 'modelsummary_list'
class(tab3_college50) <- 'modelsummary_list'
class(tab3_wage4565) <- 'modelsummary_list'
class(tab3_college65) <- 'modelsummary_list'
class(tab3_wage4580) <- 'modelsummary_list'
class(tab3_college80) <- 'modelsummary_list'
modelsummary(list('Pred. wage' = tab3_wage4550,
'College' = tab3_college50,
'Pred. wage' = tab3_wage4565,
'College' = tab3_college65,
'Pred. wage' = tab3_wage4580,
'College' = tab3_college80),
coef_map = c(college = 'College',
g_score_std = 'IQ score',
eta_fam_score_std = 'Fam score',
eta_big5_score_std = 'Big5 score',
indirect = 'Indirect effect',
total = 'Total effect'),
gof_map = list(list(raw = 'N', clean = 'Obs.',
fmt = function(x) format(x,
big.mark = ' '))),
stars = c('*' = .05, '**' = .01, '***' = 0.001)) %>%
group_tt(j = list('Born in 1950-64' = 2:3,
'Born in 1965-79' = 4:5,
'Born in 1980-94' = 6:7)) %>%
style_tt(i = -1:13, fontsize = 0.75,
tabularray_inner = "rowsep = {-.22em}, colsep = {.4em}") %>%
style_tt(i = 8, line = 'b', line_width = .001)
Born in 1950-64 | Born in 1965-79 | Born in 1980-94 | ||||
---|---|---|---|---|---|---|
Pred. wage | College | Pred. wage | College | Pred. wage | College | |
* p < 0.05, ** p < 0.01, *** p < 0.001 | ||||||
College | 0.820*** | 0.804*** | 0.651*** | |||
(0.020) | (0.016) | (0.015) | ||||
IQ score | 0.082*** | 1.018*** | 0.077*** | 0.917*** | 0.045*** | 0.788*** |
(0.009) | (0.046) | (0.007) | (0.039) | (0.007) | (0.044) | |
Fam score | 0.382*** | 0.492*** | 0.453*** | |||
(0.051) | (0.040) | (0.041) | ||||
Big5 score | 0.082* | 0.081** | 0.128*** | |||
(0.037) | (0.033) | (0.037) | ||||
Indirect effect | 0.126*** | 0.136*** | 0.096*** | |||
(0.006) | (0.005) | (0.005) | ||||
Total effect | 0.208*** | 0.213*** | 0.140*** | |||
(0.009) | (0.007) | (0.007) | ||||
Obs. | 9 496 | 9 496 | 10 488 | 10 488 | 8 382 | 8 382 |
# kable_styling(font_size = 8) %>%
# row_spec(8, hline_after = TRUE) %>%
# add_header_above(c(' ' = 1,
# 'Born in 1950-64' = 2,
# 'Born in 1965-79' = 2,
# 'Born in 1980-94' = 2))
Model
Individuals described by \(z \in Z = \Theta \times X \times Y\)
- intelligence \(\theta \in \Theta\)
- family advantage score \(x \in X\)
- Big 5 personality score \(y \in Y\)
Human capital \(H \equiv \{nc, c\}\) (no college vs college)
DPV of earnings \(W(h, z, \delta) = \sum_{a = 18}^{65}\delta^{a - 18} W(h, z, a)\)
Choose effort \(e \in \mathbb{R}_{+}\) to acquire human capital \(h = c\) given cost \(\frac{c(e)}{\Gamma(z)}\)
\[ \max_e \pi(e) \left[W(c, z, \delta) - W(nc, z, \delta)\right] - \frac{c(e)}{\Gamma(z)} \]
Solution
Denote \(A = \left(W(c, z, \delta) - W(nc, z, \delta)\right)\Gamma(z)\). Then, optimal effort solution
\[ E^\star(A; \pi) \equiv \arg\max_e \pi(e)A - e \]
\(\Pi\) is the set of functions \(\pi: \mathbb{R}_+ \rightarrow [0, 1]\) that are strictly increasing, concave, continuous at 0, \(\pi(0) = 0\), \(\lim_{x \rightarrow \infty} \pi(x) = 1\).
For \(P(A)\) increasing in \(A\) and upper semi-continuous in \(\Delta W\), \(\exists \pi \in \Pi\) such that
\[P(A) = \pi\left(E^\star(A; \pi)\right)\]
Estimation
We consider four functional forms that can describe \(P(A)\):
- Linear probability model \(P(A) = A\)
- Logit \(P(A) = (1 + e^{-A})^{-1}\)
- Logit power \(P(A) = (1 + e^{-A})^{-\kappa}, ~\kappa \in \mathbb{R}_{+}\)
- Cutoff power \(P(A) = \min\{\max\{A, 0\}^\kappa, 1\}, ~\kappa \in \mathbb{R}_{+}\)
Two-step estimation:
- Given \(\delta\) and \(\kappa\), fit \(P(A)\) to the observed college indicators.
- Grid search \(\hat{\delta}\) and \(\hat{\kappa}\) that minimise sum of squared residuals.
Results
<- read_dta('tab4.dta')
tab4 <- tab4 %>% rename(std.error = std_error)
tab4 <- tab4 %>%
tab4 mutate(print_error = if_else(is.na(boot_error),
std.error, boot_error))<- tab4 %>%
tab4 mutate(p.value = pnorm(abs(estimate) / print_error,
lower.tail = FALSE))
<- tab4 %>% nest(.by = c(spec)) %>% deframe()
tab4_list
<- list(tidy = tab4_list$LPM,
tab4_lpm glance = tab4_list$LPM %>%
distinct(rmse, mean_cp, sd_cp,
delta, power, N))<- list(tidy = tab4_list$Logit,
tab4_log glance = tab4_list$Logit %>%
distinct(rmse, mean_cp, sd_cp,
delta, power, N))<- list(tidy = tab4_list$`Logit power`,
tab4_logp glance = tab4_list$`Logit power` %>%
distinct(rmse, mean_cp, sd_cp,
delta, power, N))<- list(tidy = tab4_list$`Cutoff power`,
tab4_cutp glance = tab4_list$`Cutoff power` %>%
distinct(rmse, mean_cp, sd_cp,
delta, power, N))
class(tab4_lpm) <- 'modelsummary_list'
class(tab4_log) <- 'modelsummary_list'
class(tab4_logp) <- 'modelsummary_list'
class(tab4_cutp) <- 'modelsummary_list'
<- list(list(raw = 'N',
gof_tab clean = 'Obs.',
fmt = function(x) format(x, big.mark = ' ')),
list(raw = 'delta',
clean = '$\\delta$',
fmt = 3),
list(raw = 'power',
clean = '$\\kappa$',
fmt = 2),
list(raw = 'mean_cp',
clean = 'College premium mean',
fmt = 2),
list(raw = 'sd_cp',
clean = 'College premium sd',
fmt = 2))
modelsummary(list('LPM' = tab4_lpm,
'Logit' = tab4_log,
'Logit power\\footnotemark[1]' = tab4_logp,
'Cutoff power\\footnotemark[1]' = tab4_cutp),
statistic = '({print_error})',
coef_map = c(g_score_std = 'IQ score',
eta_fam_score_std = 'Fam score',
eta_big5_score_std = 'Big5 score',
sdd_earn_2 = 'College premium, std'),
gof_map = gof_tab,
stars = c('*' = .05, '**' = .01, '***' = 0.001),
width = c(0.27, rep((1 - 0.25) / 4, 4)),
escape = FALSE, notes = list(`1`= 'Bootstrapped standard errors')) %>%
style_tt(i = 0:15, fontsize = 0.8,
tabularray_inner = "rowsep={-.22em}, colsep = {.4em}")
LPM | Logit | Logit power\footnotemark[1] | Cutoff power\footnotemark[1] | |
---|---|---|---|---|
* p < 0.05, ** p < 0.01, *** p < 0.001 | ||||
1 Bootstrapped standard errors | ||||
IQ score | 0.118*** | 0.089*** | 0.104*** | 0.108*** |
(0.005) | (0.007) | (0.006) | (0.006) | |
Fam score | 0.061*** | 0.054*** | 0.058*** | 0.058*** |
(0.004) | (0.004) | (0.004) | (0.004) | |
Big5 score | 0.025*** | 0.038*** | 0.032*** | 0.031*** |
(0.003) | (0.004) | (0.004) | (0.004) | |
College premium, std | 0.026*** | 0.060*** | 0.042*** | 0.040*** |
(0.006) | (0.009) | (0.007) | (0.007) | |
Obs. | 31 571 | 31 571 | 31 571 | 31 571 |
$\delta$ | 0.925 | 0.925 | 0.925 | 0.925 |
$\kappa$ | 2.90 | 1.20 | ||
College premium mean | 36.95 | 36.95 | 36.95 | 36.95 |
College premium sd | 9.77 | 9.77 | 9.77 | 9.77 |
Results with polygenic scores
Results with polygenic scores
<- read_dta('tab6.dta')
tab6 <- tab6 %>% rename(std.error = std_error)
tab6 <- tab6 %>%
tab6 mutate(p.value = pnorm(abs(estimate) / std.error,
lower.tail = FALSE))
<- tab6 %>% nest(.by = c(spec)) %>% deframe()
tab6_list
<- list(tidy = tab6_list$LPM,
tab6_lpm glance = tab6_list$LPM %>%
distinct(mean_cp, sd_cp, delta, power, N))
<- list(tidy = tab6_list$Logit,
tab6_log glance = tab6_list$Logit %>%
distinct(mean_cp, sd_cp, delta, power, N))
<- list(tidy = tab6_list$`Logit power`,
tab6_logp glance = tab6_list$`Logit power` %>%
distinct(mean_cp, sd_cp, delta, power, N))
<- list(tidy = tab6_list$`Cutoff power`,
tab6_cutp glance = tab6_list$`Cutoff power` %>%
distinct(mean_cp, sd_cp, delta, power, N))
class(tab6_lpm) <- 'modelsummary_list'
class(tab6_log) <- 'modelsummary_list'
class(tab6_logp) <- 'modelsummary_list'
class(tab6_cutp) <- 'modelsummary_list'
<- list(list(raw = 'N',
gof_tab clean = 'Obs.',
fmt = function(x) format(x, big.mark = ' ')),
list(raw = 'delta',
clean = '$\\delta$',
fmt = 3),
list(raw = 'power',
clean = '$\\kappa$',
fmt = 2),
list(raw = 'mean_cp',
clean = 'College premium mean',
fmt = 2),
list(raw = 'sd_cp',
clean = 'College premium sd',
fmt = 2))
modelsummary(list('LPM' = tab6_lpm,
'Logit' = tab6_log,
'Logit power' = tab6_logp,
'Cutoff power' = tab6_cutp),
coef_map = c(pgsp_cobs_hm3p = 'IQ PGS',
etap_fam = 'Fam score',
etap_big5 = 'Big5 score',
diff4_earn = 'College premium, std'),
gof_map = gof_tab,
stars = c('*' = .05, '**' = .01, '***' = 0.001),
escape = FALSE,
width = c(0.27, rep((1 - 0.27) / 4, 4))) %>%
style_tt(i = 0:14, fontsize = .9,
tabularray_inner = "rowsep={-.2em}, colsep = {.3em}")
LPM | Logit | Logit power | Cutoff power | |
---|---|---|---|---|
* p < 0.05, ** p < 0.01, *** p < 0.001 | ||||
IQ PGS | 0.038*** | 0.034** | 0.036** | 0.037*** |
(0.011) | (0.012) | (0.012) | (0.011) | |
Fam score | 0.085*** | 0.154*** | 0.146*** | 0.134*** |
(0.008) | (0.011) | (0.011) | (0.010) | |
Big5 score | 0.109*** | 0.102** | 0.105** | 0.115*** |
(0.031) | (0.034) | (0.034) | (0.034) | |
College premium, std | 0.007** | 0.006** | 0.006** | 0.007** |
(0.002) | (0.002) | (0.002) | (0.002) | |
Obs. | 3 602 | 3 602 | 3 602 | 3 602 |
$\delta$ | 0.925 | 0.925 | 0.925 | 0.925 |
$\kappa$ | 2.90 | 1.20 | ||
College premium mean | 84.86 | 84.86 | 84.86 | 84.86 |
College premium sd | 14.27 | 14.27 | 14.27 | 14.27 |
Summary
Revisit role of intelligence, personality and family characteristics in education choice
Conditions linking econometric specification to individual optimization
Further analysis with polygenic scores
Appendices
Intelligence score
Combine individual test scores using confirmatory factor analysis
Using "tree" as default layout
Big 5 personality score
Combine individual test scores using principal component analysis
Score | Loading |
---|---|
Agreeableness | 0.4408 |
Conscientiousness | 0.4970 |
Extraversion | 0.4628 |
Neuroticism | -0.3751 |
Openness | 0.4514 |
PC1 explains 36% of variation in the data
Family advantage score
Combine education of parents and their employment status using principal component analysis
Variable | Loading (mother) | Loading (father) |
---|---|---|
Years of education | 0.4020 | 0.4286 |
Work | 0.2243 | 0.5527 |
Dead | -0.0889 | -0.2958 |
Absent | -0.2042 | -0.4023 |
PC1 explains 23% of variation in the data
METADAC vs full sample
<- read_dta('tab-bal.dta')
bal <- bal %>% nest(.by = dataset) %>% deframe()
bal_list <- list(tidy = bal_list$UKHLS,
bal_ukhls_work glance = tibble())
<- list(tidy = bal_list$METADAC,
bal_mdac_full glance = tibble())
<- list(tidy = bal_list$METADAC_work,
bal_mdac_work glance = tibble())
class(bal_ukhls_work) <- 'modelsummary_list'
class(bal_mdac_full) <- 'modelsummary_list'
class(bal_mdac_work) <- 'modelsummary_list'
modelsummary(list('Working sample' = bal_ukhls_work,
'Full sample' = bal_mdac_full,
'Working sample' = bal_mdac_work),
estimate = 'mean',
statistic = c('({sd})', '{N}'),
fmt = fmt_statistic(estimate = 3,
sd = 3,
N = function(x) format(x, big.mark = ' ')),
coef_map = c(male = 'Male',
c_age_dv = 'Age',
whitebritish = 'White British',
college = 'College',
m_work = 'Mother worked',
myedu = "Mother's years of edu",
f_work = 'Father worked',
fyedu = "Father's years of edu"),
shape = model ~ term,
escape = FALSE,
width = c(0.2, rep((1 - 0.2) / 8, 8))) %>%
style_tt(i = 0:11, fontsize = 0.75,
tabularray_inner = "rowsep={-.2em}, colsep = {.3em}") %>%
group_tt(i = list('UKHLS' = 1, 'METADAC' = 4))
Male | Age | White British | College | Mother worked | Mother's years of edu | Father worked | Father's years of edu | |
---|---|---|---|---|---|---|---|---|
Working sample | 0.440 | 41.811 | 0.818 | 0.304 | 0.600 | 11.480 | 0.823 | 11.775 |
(0.496) | (13.907) | (0.386) | (0.460) | (0.490) | (2.830) | (0.382) | (3.464) | |
31 571 | 31 571 | 31 571 | 31 571 | 31 571 | 31 571 | 31 571 | 31 571 | |
Full sample | 0.428 | 46.345 | 0.973 | 0.264 | 0.666 | 11.259 | 0.887 | 11.298 |
(0.495) | (12.901) | (0.161) | (0.441) | (0.472) | (2.369) | (0.316) | (3.524) | |
7 281 | 7 236 | 7 281 | 7 251 | 5 248 | 7 281 | 5 256 | 7 281 | |
Working sample | 0.441 | 45.865 | 1.000 | 0.304 | 0.695 | 11.759 | 0.898 | 12.070 |
(0.497) | (10.890) | (0.000) | (0.460) | (0.460) | (2.420) | (0.303) | (3.423) | |
3 413 | 3 413 | 3 413 | 3 413 | 3 413 | 3 413 | 3 413 | 3 413 |
Polygenic score
%>%
mdac ggplot(aes(x = pgs_std_cobs_hm3p,
y = g_score_std)) +
geom_point() +
geom_smooth() +
labs(x = 'IQ PGS', y = 'IQ score') +
theme_minimal()
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 978 rows containing non-finite outside the scale range
(`stat_smooth()`).
Warning: Removed 978 rows containing missing values or values outside the scale range
(`geom_point()`).
Proposition (continuously differentiable)
Redefine the effort choice problem as \(e^\star(\alpha; \pi) \equiv \arg \max_e \pi(e) - \alpha e\) where \(\alpha = A^{-1}\).
The set of endogenous probabilities is the set \(\mathcal{Q}\) of multivalued functions \(Q: \mathbb{R}_{+} \rightarrow [0,1]\) that are decreasing, closed valued, with \(\lim_{\alpha \rightarrow 0} Q(\alpha) = 1\), \(Q(\overline{\alpha}) = 0\) for some \(\overline{\alpha} >0\).
For any function \(Q \in \mathcal{Q}\) which is continuously differentiable strictly decreasing in the interval \([\underline{\alpha}, \overline{\alpha}]\), with \(Q(\underline{\alpha}) =0\), \(Q(\overline{\alpha}) =1\), there exists a continuously differentiable function \(\pi \in \Pi\) such that for all \(\alpha \in \mathbb{R}_{+}\), \(Q(\alpha) = \pi(h(\alpha; \pi))\).
Proposition proof (continuously differentiable)
Note that \(Q(\alpha)=0\) for \(\alpha > \overline{\alpha}\), so we may take the boundary condition
\[ h(\overline{\alpha}) = 0 \]
Consider the ordinary differential equation
\[ \frac{d h}{d \alpha} = \frac{Q^{\prime}}{\alpha}, \quad \alpha > 0 \]
We now define the function \(\pi\) as the solution of \(\pi(h(\alpha)) = Q(\alpha)\). The function \(h\) satisfies the differential equation, which is the first order necessary and sufficient conditions for optimal effort choice problem, namely \(\pi^{\prime}(h(\alpha)) = \alpha\). Thus, our claim follows.
Logit power
<- function(x, kappa) (1 + exp(-x))^(-kappa)
logp_fun <- c(-5, 5)
logp_xlim ggplot() +
geom_function(fun = function(x) logp_fun(x, 0.1),
aes(colour = '0.1'), xlim = logp_xlim) +
geom_function(fun = function(x) logp_fun(x, 0.5),
aes(colour = '0.5'), xlim = logp_xlim) +
geom_function(fun = function(x) logp_fun(x, 1),
aes(colour = '1'), xlim = logp_xlim) +
geom_function(fun = function(x) logp_fun(x, 2),
aes(colour = '2'), xlim = logp_xlim) +
geom_function(fun = function(x) logp_fun(x, 4),
aes(colour = '4'), xlim = logp_xlim) +
labs(x = 'A', y = 'P(A)', colour = '') +
scale_colour_brewer(palette = 'Set1',
labels = c(expression(kappa == 0.1),
expression(kappa == 0.5),
expression(kappa == 1),
expression(kappa == 2),
expression(kappa == 4))) +
theme_minimal() +
theme(legend.position = c(0.85, 0.4))
Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
3.5.0.
ℹ Please use the `legend.position.inside` argument of `theme()` instead.
Cutoff power
<- function(x, kappa) pmin(pmax(x, 0)^kappa, 1)
cutp_fun <- c(-0.2, 1.2)
cutp_xlim ggplot() +
geom_function(fun = function(x) cutp_fun(x, 0.1),
aes(colour = '0.1'), xlim = cutp_xlim) +
geom_function(fun = function(x) cutp_fun(x, 0.5),
aes(colour = '0.5'), xlim = cutp_xlim) +
geom_function(fun = function(x) cutp_fun(x, 1),
aes(colour = '1'), xlim = cutp_xlim) +
geom_function(fun = function(x) cutp_fun(x, 2),
aes(colour = '2'), xlim = cutp_xlim) +
geom_function(fun = function(x) cutp_fun(x, 4),
aes(colour = '4'), xlim = cutp_xlim) +
labs(x = 'A', y = 'P(A)', colour = '') +
scale_colour_brewer(palette = 'Set1',
labels = c(expression(kappa == 0.1),
expression(kappa == 0.5),
expression(kappa == 1),
expression(kappa == 2),
expression(kappa == 4))) +
theme_minimal() +
theme(legend.position = c(0.85, 0.4))