library(kirkegaard)
## Loading required package: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.1.9000 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.2.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Loading required package: magrittr
##
##
## Attaching package: 'magrittr'
##
##
## The following object is masked from 'package:purrr':
##
## set_names
##
##
## The following object is masked from 'package:tidyr':
##
## extract
##
##
## Loading required package: weights
##
## Loading required package: assertthat
##
##
## Attaching package: 'assertthat'
##
##
## The following object is masked from 'package:tibble':
##
## has_name
##
##
## Loading required package: psych
##
##
## Attaching package: 'psych'
##
##
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
##
##
## Loading required package: robustbase
##
##
## Attaching package: 'kirkegaard'
##
##
## The following object is masked from 'package:psych':
##
## rescale
##
##
## The following object is masked from 'package:assertthat':
##
## are_equal
##
##
## The following object is masked from 'package:purrr':
##
## is_logical
##
##
## The following object is masked from 'package:base':
##
## +
load_packages(
tidyverse,
glmnet,
Matrix,
pROC,
knitr
)
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
##
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
##
## Loaded glmnet 4.1-10
## Type 'citation("pROC")' for a citation.
##
## Attaching package: 'pROC'
##
## The following objects are masked from 'package:stats':
##
## cov, smooth, var
theme_set(theme_bw())
options(
digits = 3
)
Danish citizenship by naturalization requires an act of parliament listing every person granted citizenship. These laws (“Lov om indfødsrets meddelelse”) have been published 1-3 times per year since at least 1987.
We downloaded all 89 laws (1987-2025) via the retsinformation-api.dk REST API and parsed names, locations, and birth countries from the structured JSON.
d <- read_rds("data/citizenship_grants.rds")
glimpse(d)
## Rows: 141,780
## Columns: 20
## $ law_year <int> 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 198…
## $ law_number <int> 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 1…
## $ law_short <chr> "LOV nr 157 af 23/03/1988", "LOV nr 157 af 23/03/19…
## $ paragraph <chr> "§ 1.", "§ 1.", "§ 1.", "§ 1.", "§ 1.", "§ 1.", "§ …
## $ section_type <chr> "Direct grant", "Direct grant", "Direct grant", "Di…
## $ entry_number <chr> "100)", "101)", "102)", "103)", "104)", "105)", "10…
## $ name <chr> "Ilhan Caglar", "Ba Tuan Cao", "Raif Cengiz", "Emil…
## $ first_name <chr> "Ilhan", "Ba", "Raif", "Emilia", "Marta", "Fatiha",…
## $ last_name <chr> "Caglar", "Cao", "Cengiz", "Flores", "Lopez", "Azam…
## $ location <chr> "Næstved", "Frederikshavn", "Greve", "København", "…
## $ birth_country <chr> "Tyrkiet", "Vietnam", "Tyrkiet", "Chile", "El Salva…
## $ country_clean <chr> "Tyrkiet", "Vietnam", "Tyrkiet", "Chile", "El Salva…
## $ region_birth <chr> "MENAP/Turkey", "Non-Western other", "MENAP/Turkey"…
## $ region <chr> "MENAP/Turkey", "Non-Western other", "MENAP/Turkey"…
## $ ethnicity2 <chr> "Muslim", "Vietnamese", "Muslim", "Hispanic", "Hisp…
## $ origin_pred <chr> "Turkish", "Vietnamese", "Turkish", "Latin American…
## $ origin_conf <dbl> 0.725, 0.688, 0.835, 0.867, 0.725, 0.941, 0.984, 0.…
## $ pred_region <chr> "MENAP/Turkey", "Non-Western other", "MENAP/Turkey"…
## $ origin_simple <chr> "Turkish", "Vietnamese", "Turkish", "Romance", "Rom…
## $ origin_simple_conf <dbl> 0.780, 0.780, 0.864, 0.846, 0.843, 0.987, 0.910, 0.…
cat("Total entries:", nrow(d), "\n")
## Total entries: 141780
cat("Laws:", n_distinct(paste(d$law_year, d$law_number)), "\n")
## Laws: 85
cat("Year range:", min(d$law_year), "-", max(d$law_year), "\n")
## Year range: 1988 - 2025
d |>
count(law_year, name = "n_grants") |>
ggplot(aes(x = law_year, y = n_grants)) +
geom_col(fill = "#377EB8") +
scale_x_continuous(breaks = seq(1988, 2025, 2)) +
labs(title = "Danish citizenship grants per year", x = "Year", y = "Count") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
first_names <- d |> count(first_name, sort = TRUE)
last_names <- d |> count(last_name, sort = TRUE)
first_names |>
head(30) |>
mutate(first_name = fct_reorder(first_name, n)) |>
ggplot(aes(x = n, y = first_name)) +
geom_col(fill = "#377EB8") +
geom_text(aes(label = scales::comma(n)), hjust = -0.1, size = 3) +
scale_x_continuous(expand = expansion(mult = c(0, 0.15))) +
labs(title = "Top 30 first names in Danish citizenship grants (1988-2025)",
x = "Count", y = NULL)
muhammad_variants <- c("Mohammad", "Mohamed", "Mohammed", "Mohamad", "Mehmet",
"Muhammed", "Muhamed", "Mohamud", "Mohamoud", "Muhamad",
"Muhammet", "Muhammad", "Mohammud", "Mohamod", "Mohammod")
first_names_merged <- first_names |>
rename(freq = n) |>
mutate(first_name_merged = case_when(
first_name %in% muhammad_variants ~ "Mohammad*",
first_name %in% c("Ahmad", "Ahmed") ~ "Ahmad*",
first_name %in% c("Fatima", "Fatma", "Fatime", "Fatimeh", "Fatimah") ~ "Fatima*",
first_name %in% c("Hassan", "Hasan") ~ "Hassan*",
first_name %in% c("Hussein", "Hussain", "Husein", "Husain") ~ "Hussein*",
first_name %in% c("Mustafa", "Mustapha") ~ "Mustafa*",
first_name %in% c("Omar", "Omer", "Ömer") ~ "Omar*",
first_name %in% c("Sara", "Sarah") ~ "Sara*",
first_name %in% c("Mariam", "Maryam", "Miriam", "Miryam") ~ "Mariam*",
first_name %in% c("Ibrahim", "Ebrahim") ~ "Ibrahim*",
first_name %in% c("Mahmoud", "Mahmud", "Mahmod") ~ "Mahmoud*",
first_name %in% c("Khaled", "Khalid") ~ "Khaled*",
first_name %in% c("Natalia", "Nataliya", "Natalya", "Natalie", "Nataliia", "Natalija") ~ "Natalia*",
first_name %in% c("Elena", "Jelena", "Yelena") ~ "Elena*",
TRUE ~ first_name
)) |>
summarise(count = sum(freq), .by = first_name_merged) |>
arrange(desc(count))
first_names_merged |>
head(30) |>
mutate(first_name_merged = fct_reorder(first_name_merged, count)) |>
ggplot(aes(x = count, y = first_name_merged)) +
geom_col(fill = "#377EB8") +
geom_text(aes(label = scales::comma(count)), hjust = -0.1, size = 3) +
scale_x_continuous(expand = expansion(mult = c(0, 0.15))) +
labs(title = "Top 30 first names (spelling variants merged)",
subtitle = "* Mohammad/Mohamed/Mohammed/Mohamad/Mehmet/Muhammad etc.",
x = "Count", y = NULL)
Mohammad* at 3971 is 2.8% of all naturalizations.
last_names |>
head(30) |>
mutate(last_name = fct_reorder(last_name, n)) |>
ggplot(aes(x = n, y = last_name)) +
geom_col(fill = "#E41A1C") +
geom_text(aes(label = scales::comma(n)), hjust = -0.1, size = 3) +
scale_x_continuous(expand = expansion(mult = c(0, 0.15))) +
labs(title = "Top 30 last names in Danish citizenship grants (1988-2025)",
x = "Count", y = NULL)
The laws provide two sources of origin information:
region_by_year <- d |>
filter(!is.na(region)) |>
count(law_year, region) |>
group_by(law_year) |>
mutate(total = sum(n), pct = n / total * 100) |>
ungroup() |>
mutate(region = factor(region, levels = c("Nordic", "Western", "MENAP/Turkey", "Non-Western other")))
cols_region <- c("Nordic" = "#4DAF4A", "Western" = "#377EB8",
"MENAP/Turkey" = "#E41A1C", "Non-Western other" = "#FF7F00")
ggplot(region_by_year, aes(x = law_year, y = pct, fill = region)) +
geom_col() +
annotate("rect", xmin = 1999.5, xmax = 2020.5, ymin = 0, ymax = Inf,
alpha = 0.15, fill = "grey50") +
annotate("text", x = 2010, y = 50, label = "No region data\n(2000-2020)",
size = 3.5, color = "grey30") +
scale_fill_manual(values = cols_region) +
scale_x_continuous(breaks = seq(1988, 2025, 2)) +
scale_y_continuous(labels = \(x) paste0(x, "%")) +
labs(title = "Danish citizenship grants by origin region (official data)",
x = "Year", y = "Percentage", fill = "Region") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Note: the 2021-2025 region labels reflect current passport held, not ethnic origin. Many “Nordic” passport holders have non-Nordic names (immigrants who naturalized in Sweden/Norway first).
We trained a character n-gram ridge regression classifier to predict ethnic origin from names:
m21 <- tribble(
~Origin, ~N, ~Recall, ~Precision, ~F1, ~AUC,
"Arab", 4808, 87.3, 81.2, 84.1, 0.978,
"Iranian", 4652, 90.7, 87.2, 88.9, 0.990,
"East European", 3502, 86.3, 84.9, 85.6, 0.982,
"Turkish", 3337, 96.7, 91.6, 94.1, 0.997,
"Vietnamese", 2235, 97.9, 95.5, 96.7, 0.998,
"Sri Lankan", 1865, 94.2, 97.1, 95.6, 0.998,
"North African", 1369, 68.8, 72.3, 70.5, 0.959,
"Southeast Asian", 1091, 61.8, 62.6, 62.2, 0.957,
"Pakistani", 1313, 78.6, 74.8, 76.7, 0.986,
"Germanic", 1095, 71.9, 58.6, 64.6, 0.973,
"Latin American", 771, 52.1, 61.5, 56.4, 0.967,
"Anglo", 656, 51.2, 51.6, 51.4, 0.958,
"East African", 459, 36.2, 64.2, 46.3, 0.935,
"Nordic", 391, 40.0, 55.2, 46.4, 0.960,
"Chinese", 387, 71.4, 75.0, 73.2, 0.988,
"West African", 362, 25.0, 51.4, 33.6, 0.933,
"South Asian", 332, 35.3, 57.1, 43.6, 0.888,
"French/South European", 364, 27.7, 34.6, 30.8, 0.923,
"Afghan", 146, 15.4, 57.1, 24.3, 0.950,
"Somali/Arab", 122, 50.0, 61.9, 55.3, 0.943,
"East Asian other", 96, 11.8, 33.3, 17.4, 0.964
)
kable(m21, caption = "21-group elastic net model (train/test split)")
| Origin | N | Recall | Precision | F1 | AUC |
|---|---|---|---|---|---|
| Arab | 4808 | 87.3 | 81.2 | 84.1 | 0.978 |
| Iranian | 4652 | 90.7 | 87.2 | 88.9 | 0.990 |
| East European | 3502 | 86.3 | 84.9 | 85.6 | 0.982 |
| Turkish | 3337 | 96.7 | 91.6 | 94.1 | 0.997 |
| Vietnamese | 2235 | 97.9 | 95.5 | 96.7 | 0.998 |
| Sri Lankan | 1865 | 94.2 | 97.1 | 95.6 | 0.998 |
| North African | 1369 | 68.8 | 72.3 | 70.5 | 0.959 |
| Southeast Asian | 1091 | 61.8 | 62.6 | 62.2 | 0.957 |
| Pakistani | 1313 | 78.6 | 74.8 | 76.7 | 0.986 |
| Germanic | 1095 | 71.9 | 58.6 | 64.6 | 0.973 |
| Latin American | 771 | 52.1 | 61.5 | 56.4 | 0.967 |
| Anglo | 656 | 51.2 | 51.6 | 51.4 | 0.958 |
| East African | 459 | 36.2 | 64.2 | 46.3 | 0.935 |
| Nordic | 391 | 40.0 | 55.2 | 46.4 | 0.960 |
| Chinese | 387 | 71.4 | 75.0 | 73.2 | 0.988 |
| West African | 362 | 25.0 | 51.4 | 33.6 | 0.933 |
| South Asian | 332 | 35.3 | 57.1 | 43.6 | 0.888 |
| French/South European | 364 | 27.7 | 34.6 | 30.8 | 0.923 |
| Afghan | 146 | 15.4 | 57.1 | 24.3 | 0.950 |
| Somali/Arab | 122 | 50.0 | 61.9 | 55.3 | 0.943 |
| East Asian other | 96 | 11.8 | 33.3 | 17.4 | 0.964 |
Overall: Accuracy 81.1%, Macro F1 61.8, Weighted F1 80.4, Macro AUC 0.963, Weighted AUC 0.980
Groups merged for cleaner classification:
m10 <- tribble(
~Origin, ~N, ~Recall, ~Precision, ~F1, ~AUC,
"MENAP", 12410, 97.5, 92.7, 95.0, 0.991,
"East European", 3502, 86.8, 85.8, 86.3, 0.986,
"Turkish", 3337, 96.3, 93.2, 94.7, 0.997,
"Vietnamese", 2235, 97.7, 96.8, 97.2, 0.998,
"South Asian", 2197, 87.5, 95.8, 91.5, 0.985,
"Germanic", 2142, 76.7, 70.4, 73.4, 0.973,
"Romance", 1135, 57.7, 65.5, 61.4, 0.963,
"Southeast Asian", 1091, 51.9, 61.8, 56.4, 0.958,
"Sub-Saharan African", 821, 34.7, 67.1, 45.7, 0.920,
"East Asian", 483, 65.6, 85.9, 74.4, 0.975
)
kable(m10, caption = "10-group ridge model (nested 10x10 CV, unbiased)")
| Origin | N | Recall | Precision | F1 | AUC |
|---|---|---|---|---|---|
| MENAP | 12410 | 97.5 | 92.7 | 95.0 | 0.991 |
| East European | 3502 | 86.8 | 85.8 | 86.3 | 0.986 |
| Turkish | 3337 | 96.3 | 93.2 | 94.7 | 0.997 |
| Vietnamese | 2235 | 97.7 | 96.8 | 97.2 | 0.998 |
| South Asian | 2197 | 87.5 | 95.8 | 91.5 | 0.985 |
| Germanic | 2142 | 76.7 | 70.4 | 73.4 | 0.973 |
| Romance | 1135 | 57.7 | 65.5 | 61.4 | 0.963 |
| Southeast Asian | 1091 | 51.9 | 61.8 | 56.4 | 0.958 |
| Sub-Saharan African | 821 | 34.7 | 67.1 | 45.7 | 0.920 |
| East Asian | 483 | 65.6 | 85.9 | 74.4 | 0.975 |
Overall: Accuracy 88.3%, Macro F1 77.6, Weighted F1 87.8, Macro AUC 0.975, Weighted AUC 0.985
origin_simple_year <- d |>
count(law_year, origin_simple) |>
group_by(law_year) |>
mutate(total = sum(n), pct = n / total * 100) |>
ungroup() |>
mutate(origin_simple = factor(origin_simple, levels = c(
"Germanic", "Romance", "East European",
"Turkish", "MENAP",
"South Asian", "Vietnamese", "East Asian", "Southeast Asian",
"Sub-Saharan African"
)))
simple_cols <- c(
"Germanic" = "#1b9e77", "Romance" = "#a6cee3", "East European" = "#e6ab02",
"Turkish" = "#d95f02", "MENAP" = "#e41a1c",
"South Asian" = "#984ea3", "Vietnamese" = "#00bfc4",
"East Asian" = "#377eb8", "Southeast Asian" = "#80b1d3",
"Sub-Saharan African" = "#ff7f00"
)
ggplot(origin_simple_year, aes(x = law_year, y = n, fill = origin_simple)) +
geom_col() +
scale_fill_manual(values = simple_cols) +
scale_x_continuous(breaks = seq(1988, 2025, 2)) +
labs(title = "Danish citizenship grants by predicted ethnic origin (1988-2025)",
subtitle = "10 groups, ridge classifier on character n-grams (88% accuracy)",
x = "Year", y = "Number of grants", fill = "Origin") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(origin_simple_year, aes(x = law_year, y = pct, fill = origin_simple)) +
geom_col() +
scale_fill_manual(values = simple_cols) +
scale_x_continuous(breaks = seq(1988, 2025, 2)) +
scale_y_continuous(labels = \(x) paste0(x, "%")) +
labs(title = "Danish citizenship grants by predicted ethnic origin (1988-2025)",
subtitle = "10 groups, ridge classifier on character n-grams (88% accuracy)",
x = "Year", y = "Percentage", fill = "Origin") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
origin_by_year <- d |>
count(law_year, origin_pred) |>
group_by(law_year) |>
mutate(total = sum(n), pct = n / total * 100) |>
ungroup() |>
mutate(origin_pred = factor(origin_pred, levels = c(
"Nordic", "Germanic", "Anglo", "French/South European",
"East European", "Latin American",
"Turkish", "Arab", "Iranian", "North African", "Somali/Arab", "Afghan",
"Pakistani", "Sri Lankan", "South Asian",
"Vietnamese", "Chinese", "Southeast Asian", "East Asian other",
"East African", "West African"
)))
origin_cols <- c(
"Nordic" = "#1b9e77", "Germanic" = "#66a61e", "Anglo" = "#7570b3",
"French/South European" = "#a6cee3", "East European" = "#e6ab02",
"Latin American" = "#e7298a",
"Turkish" = "#d95f02", "Arab" = "#e41a1c", "Iranian" = "#fb8072",
"North African" = "#fdb462", "Somali/Arab" = "#bc80bd", "Afghan" = "#ccebc5",
"Pakistani" = "#984ea3", "Sri Lankan" = "#8dd3c7", "South Asian" = "#bebada",
"Vietnamese" = "#00bfc4", "Chinese" = "#377eb8", "Southeast Asian" = "#80b1d3",
"East Asian other" = "#f781bf",
"East African" = "#ff7f00", "West African" = "#b15928"
)
ggplot(origin_by_year, aes(x = law_year, y = pct, fill = origin_pred)) +
geom_col() +
scale_fill_manual(values = origin_cols) +
scale_x_continuous(breaks = seq(1988, 2025, 2)) +
scale_y_continuous(labels = \(x) paste0(x, "%")) +
labs(title = "Danish citizenship grants by predicted name origin (21 groups)",
x = "Year", y = "Percentage", fill = "Origin") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
We validated predictions against Statistics Denmark (DST) table DKSTAT which records citizenships granted by previous nationality.
knitr::include_graphics("figs/dst_validation.png")
Overall correlation of percentage shares: r = 0.82. Best validated groups: Vietnamese (r=0.98), Sri Lankan (r=0.97), Germanic (r=0.96), Anglo (r=0.96).
knitr::include_graphics("figs/model_summary.png")
knitr::include_graphics("figs/confusion_matrix_10group.png")
MENAP names are classified with 98% recall. Sub-Saharan African names leak 34% to MENAP due to Muslim naming overlap. The European groups (Germanic, Romance, East European) show moderate cross-confusion due to shared cultural origins.
The AUC measures how well the model separates true cases from non-cases. Blue = true members of the group, red = everyone else. Good separation = high AUC.
knitr::include_graphics("figs/confidence_auc_10group.png")
knitr::include_graphics("figs/confidence_auc_21group.png")
knitr::include_graphics("figs/confidence_ridge.png")
knitr::include_graphics("figs/origin_simple_pooled.png")
About half of all naturalizations (MENAP 43% + Turkish 10% = 53%) involve people with Muslim-origin names.
France also publishes naturalization decrees in the Journal Officiel, listing every person with their name, birth date, and birth country. We extracted one decree (June 2025, n=631) and applied the same classifier.
knitr::include_graphics("figs/france_vs_denmark_2025.png")
MENAP names dominate France even more (65% vs 43%), reflecting the Maghreb colonial connection. Denmark has more Turkish (guest worker legacy) and East European (EU expansion) naturalizations. France has more Sub-Saharan African (francophone Africa). Note that birth country can be misleading for France-born children of immigrants – the name-based prediction captures ethnic origin regardless of birthplace.
#versions
write_sessioninfo()
## R version 4.5.3 (2026-03-11)
## Platform: x86_64-pc-linux-gnu
## Running under: Linux Mint 21.1
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0 LAPACK version 3.10.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=en_DK.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_DK.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_DK.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Europe/Brussels
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] knitr_1.50 pROC_1.19.0.1 glmnet_4.1-10
## [4] Matrix_1.7-4 kirkegaard_2025-11-19 robustbase_0.99-6
## [7] psych_2.5.6 assertthat_0.2.1 weights_1.1.2
## [10] magrittr_2.0.4 lubridate_1.9.4 forcats_1.0.1
## [13] stringr_1.6.0 dplyr_1.1.4 purrr_1.2.0
## [16] readr_2.1.5 tidyr_1.3.1 tibble_3.3.0
## [19] ggplot2_4.0.1.9000 tidyverse_2.0.0
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.2.1 farver_2.1.2 S7_0.2.1 fastmap_1.2.0
## [5] digest_0.6.39 rpart_4.1.24 timechange_0.3.0 lifecycle_1.0.4
## [9] cluster_2.1.8.2 survival_3.8-6 gdata_3.0.1 compiler_4.5.3
## [13] rlang_1.1.6.9000 Hmisc_5.2-4 sass_0.4.10 tools_4.5.3
## [17] yaml_2.3.10 data.table_1.17.8 labeling_0.4.3 htmlwidgets_1.6.4
## [21] mnormt_2.1.1 RColorBrewer_1.1-3 withr_3.0.2 foreign_0.8-91
## [25] nnet_7.3-20 grid_4.5.3 jomo_2.7-6 colorspace_2.1-2
## [29] mice_3.18.0 scales_1.4.0 gtools_3.9.5 iterators_1.0.14
## [33] MASS_7.3-65 cli_3.6.5 rmarkdown_2.30 reformulas_0.4.1
## [37] generics_0.1.4 rstudioapi_0.17.1 tzdb_0.5.0 minqa_1.2.8
## [41] cachem_1.1.0 splines_4.5.3 parallel_4.5.3 base64enc_0.1-3
## [45] vctrs_0.6.5 boot_1.3-32 jsonlite_2.0.0 hms_1.1.3
## [49] mitml_0.4-5 Formula_1.2-5 htmlTable_2.4.3 foreach_1.5.2
## [53] jquerylib_0.1.4 glue_1.8.0 DEoptimR_1.1-4 nloptr_2.2.1
## [57] pan_1.9 codetools_0.2-20 stringi_1.8.7 gtable_0.3.6
## [61] shape_1.4.6.1 lme4_1.1-37 pillar_1.11.1 htmltools_0.5.8.1
## [65] R6_2.6.1 Rdpack_2.6.4 evaluate_1.0.5 lattice_0.22-7
## [69] png_0.1-8 rbibutils_2.3 backports_1.5.0 broom_1.0.11
## [73] bslib_0.9.0 Rcpp_1.1.0 gridExtra_2.3 nlme_3.1-168
## [77] checkmate_2.3.3 xfun_0.57 pkgconfig_2.0.3
#write data to file for reuse
d %>% write_rds("data/data_for_reuse.rds")
#OSF
if (F) {
library(osfr)
#login
osf_auth(readr::read_lines("~/.config/osf_token"))
#the project we will use
osf_proj = osf_retrieve_node("https://osf.io/XXX/")
#upload all files in project
#overwrite existing (versioning)
osf_upload(
osf_proj,
path = c("data", "figures", "papers", "notebook.Rmd", "notebook.html", "sessions_info.txt"),
conflicts = "overwrite"
)
}