From 9ec8daaf61f0cf0bb33f688da73cb9951537ed80 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Thu, 13 Feb 2025 12:36:29 +0100 Subject: [PATCH 01/28] Add some attempt at tidying data --- R/dst_tidy.R | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 R/dst_tidy.R diff --git a/R/dst_tidy.R b/R/dst_tidy.R new file mode 100644 index 0000000..117b7ed --- /dev/null +++ b/R/dst_tidy.R @@ -0,0 +1,61 @@ +dst_tidy <- function(table) { + out <- table |> + tidy_decide_agg_type() |> + dplyr::rename( + agegroup = ALDER, + time = TID, + value = value + ) |> + dplyr::mutate( + area_num = strsplit(area, " ")[[1]][1] |> + as.numeric() + ) + + class(out) <- c("dkstat", class(out)) +} + +tidy_decide_agg_type <- function(table) { + if ("KOMGRP" %in% colnames(table)) { + table |> + dplyr::mutate( + area_agg_cat = "municipality", + ) |> + dplyr::rename( + area = KOMGRP + ) + } +} + +tidy_municipalities <- function(table) { + table |> + dplyr::mutate( + area_type = dplyr::if_else( + strsplit(area, " ")[[1]][1] |> + as.numeric() < 99, "Aggregate" + ) + ) +} + +dst_tidy_gpt <- function(table) { + table |> + dplyr::rename( + area = KOMGRP, + agegroup = ALDER, + time = TID, + value = value + ) |> + dplyr::mutate( + # Extract the number from the start of area + area_num = as.numeric(sub(" .*", "", area)), + # Create area type classification + area_type = dplyr::case_when( + area_num == 0 ~ "National", + area_num >= 1 & area_num <= 10 ~ "Municipality group", + area_num >= 100 & area_num <= 999 ~ "Municipality", + TRUE ~ NA_character_ + ), + # Remove the numbers and leading space from area names + area = sub("^[0-9]+ ", "", area) + ) |> + dplyr::select(-area_num) # Remove the temporary number column +} From 874ca6128548efe9138ffc289ddb5ad381f39b82 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Thu, 13 Feb 2025 12:37:02 +0100 Subject: [PATCH 02/28] Remove unused code --- R/dst_tidy.R | 61 ---------------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 R/dst_tidy.R diff --git a/R/dst_tidy.R b/R/dst_tidy.R deleted file mode 100644 index 117b7ed..0000000 --- a/R/dst_tidy.R +++ /dev/null @@ -1,61 +0,0 @@ -dst_tidy <- function(table) { - out <- table |> - tidy_decide_agg_type() |> - dplyr::rename( - agegroup = ALDER, - time = TID, - value = value - ) |> - dplyr::mutate( - area_num = strsplit(area, " ")[[1]][1] |> - as.numeric() - ) - - class(out) <- c("dkstat", class(out)) -} - -tidy_decide_agg_type <- function(table) { - if ("KOMGRP" %in% colnames(table)) { - table |> - dplyr::mutate( - area_agg_cat = "municipality", - ) |> - dplyr::rename( - area = KOMGRP - ) - } -} - -tidy_municipalities <- function(table) { - table |> - dplyr::mutate( - area_type = dplyr::if_else( - strsplit(area, " ")[[1]][1] |> - as.numeric() < 99, "Aggregate" - ) - ) -} - -dst_tidy_gpt <- function(table) { - table |> - dplyr::rename( - area = KOMGRP, - agegroup = ALDER, - time = TID, - value = value - ) |> - dplyr::mutate( - # Extract the number from the start of area - area_num = as.numeric(sub(" .*", "", area)), - # Create area type classification - area_type = dplyr::case_when( - area_num == 0 ~ "National", - area_num >= 1 & area_num <= 10 ~ "Municipality group", - area_num >= 100 & area_num <= 999 ~ "Municipality", - TRUE ~ NA_character_ - ), - # Remove the numbers and leading space from area names - area = sub("^[0-9]+ ", "", area) - ) |> - dplyr::select(-area_num) # Remove the temporary number column -} From afb1f2ff553a52ca1e7365dd3001e8ea8f932aa8 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Thu, 13 Feb 2025 12:39:42 +0100 Subject: [PATCH 03/28] Begin integration of geodk and dkstat packages This is the inital commit for the integration between the packages. Expect many more. Only two types of geographic data have been added yet --- .Rbuildignore | 2 + .gitignore | 3 + DESCRIPTION | 5 +- R/determine_geographic_properties.R | 41 ++ R/dst_get_all_data.R | 4 +- R/s3_constructors.R | 18 + R/utils.R | 707 ++++++++++++++++++++++++++++ data-raw/dkstat_groups.R | 164 +++++++ data-raw/komgrp.csv | 104 ++++ data/kom_omraade.rda | Bin 0 -> 1108 bytes data/komgrp.rda | Bin 0 -> 1544 bytes dkstat.Rproj | 2 +- vignettes/.gitignore | 2 + vignettes/refs.bib | 11 + vignettes/tech-specs-for-geodk.Rmd | 101 ++++ 15 files changed, 1161 insertions(+), 3 deletions(-) create mode 100644 R/determine_geographic_properties.R create mode 100644 R/s3_constructors.R create mode 100644 R/utils.R create mode 100644 data-raw/dkstat_groups.R create mode 100644 data-raw/komgrp.csv create mode 100644 data/kom_omraade.rda create mode 100644 data/komgrp.rda create mode 100644 vignettes/.gitignore create mode 100644 vignettes/refs.bib create mode 100644 vignettes/tech-specs-for-geodk.Rmd diff --git a/.Rbuildignore b/.Rbuildignore index 57f6c22..b7cfc08 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -9,3 +9,5 @@ ^docs$ ^README.Rmd$ ^.lintr$ +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index 7d41385..4bf787e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ read-and-delete-me test_script.R .DS_Store docs +inst/doc +/doc/ +/Meta/ diff --git a/DESCRIPTION b/DESCRIPTION index b8ccf01..8e168ec 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,6 +22,8 @@ Imports: lubridate, stringr Suggests: + knitr, + rmarkdown, testthat Encoding: UTF-8 Roxygen: list(markdown = TRUE) @@ -31,5 +33,6 @@ RoxygenNote: 7.3.2 X-schema.org-isPartOf: http://ropengov.org/ X-schema.org-keywords: ropengov Depends: - R (>= 2.10) + R (>= 3.5) LazyData: true +VignetteBuilder: knitr diff --git a/R/determine_geographic_properties.R b/R/determine_geographic_properties.R new file mode 100644 index 0000000..7dbf075 --- /dev/null +++ b/R/determine_geographic_properties.R @@ -0,0 +1,41 @@ +# determine_geographic_properties.R +# This file contains the logic to decide what kind of geographic information is +# included in a given dataset. The function is mainly used in +# `dst_get_all_data()` + +determine_geographic_properties <- function(df) { + clnms <- colnames(df) + + if (is_geographic(clnms)) { + chosen_constructor <- choose_geo_class(df, clnms) + chosen_constructor(df) + } else { + return(df) + } +} + +is_geographic <- function(varnames) { + # If any of the variable names are recorded as geographic, return TRUE + any(varnames %in% geo_vars) +} + +choose_geo_class <- function(df, clnms) { + g_vars <- intersect(geo_vars, clnms) + + if (g_vars == "OMRÅDE") { + if (identical(unique(df$OMRÅDE), geographic_vectors[["kom_omraade"]])) { + new_dkstat_kom_omraade + } else if (identical(unique(df$OMRÅDE), geographic_vectors[["komgrp"]])) { + new_dkstat_KOMGRP + } + } + + if (g_vars == "KOMGRP") { + if (identical(unique(df$KOMGRP), geographic_vectors[["kom_omraade"]])) { + new_dkstat_kom_omraade + } else if (identical(unique(df$KOMGRP), geographic_vectors[["komgrp"]])) { + new_dkstat_KOMGRP + } + } + +} diff --git a/R/dst_get_all_data.R b/R/dst_get_all_data.R index 9db3892..70479e0 100644 --- a/R/dst_get_all_data.R +++ b/R/dst_get_all_data.R @@ -23,13 +23,15 @@ dst_get_all_data <- function(table, lang = "da", parse_dst_tid = TRUE) { query <- get_var_options(metadata, variable_names) # Request table with query params - data <- dst_get_data( + response <- dst_get_data( table = table, query = query, lang = lang, parse_dst_tid = parse_dst_tid ) + data <- determine_geographic_properties(response) + return(data) } diff --git a/R/s3_constructors.R b/R/s3_constructors.R new file mode 100644 index 0000000..dcf4b8d --- /dev/null +++ b/R/s3_constructors.R @@ -0,0 +1,18 @@ +# s3_constructors.R +# This file defines all the s3 constructors needed for the appropriate dispatch +# of geographic matching in `{geodk}` (or other packages that might benefit from +# knowing the geographic type). The class is assigned "after the fact", as +# Wickham calls it, ensuring that the usual behaviour of a data.frame is +# preserved for all the functions that don't know about these special classes. + +new_dkstat_KOMGRP <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_KOMGRP", class(x)) + return(x) +} + +new_dkstat_kom_omraade <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_kom_omraade", class(x)) + return(x) +} diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..8b33a4b --- /dev/null +++ b/R/utils.R @@ -0,0 +1,707 @@ +geographic_vectors <- list( + "komgrp" = dkstat::komgrp, + "kom_omraade" = dkstat::kom_omraade +) + + +geo_vars <- c( + "OMRÅDE", + "HOVEDDELE", + "BYER", + "KOMK", + "OER", + "PNR20", # Postal code + "SOGN", + "KOMGRP", + "REGLAND", + "KOMMUNEDK", + "LANDSDEL", + "OMR20", + "AMT", + "BEBO", + "REGION", + "BOPREG", + "BOP", + "PROVSTI", + "BOPKOM", + "BOPOMR", + "LONGRP", + "BOPLANDK", + "BOPKOMGRP", + "KMDR", + "LANDDEL" +) + +# c( +# "AKTOER", +# "FINANSKILDE1", +# "FINANSKILDE", +# "MODSEKTOR", +# "LAND", +# "RESTANCE", +# "DELTYP", +# "BRUTNETUDG", +# "FUNK1", +# "DRANST", +# "ART", +# "GRUPPERING", +# "DRANST1", +# "REGI07A", +# "REGI07", +# "TVGRP", +# "NATGRUP", +# "SKATPCT", +# "INDKOMST", +# "SKATGRL", +# "SKATPRO", +# "SKAT", +# "INDSKAT", +# "POST", +# "INDUDBOP", +# "UHBEGREB", +# "INDUD", +# "BALANC", +# "INDSEK", +# "VALUTA", +# "VIRKSTRRDA", +# "EJERSKAB", +# "HOVBRAN", +# "KONC", +# "PLAND", +# "HANDEL", +# "LANDGRP", +# "VARE", +# "DATAKILDE", +# "SITC", +# "INDEKSTYPE", +# "SAESON2", +# "NATION", +# "DATA", +# "UDSEK", +# "INSTRNAT", +# "RETNAT", +# "UDLBRANCHE", +# "INDLBRANCHE", +# "VAREGR", +# "HOVED", +# "VARGR", +# "BAGOPL", +# "HUSSTAND", +# "SAMIND", +# "BOLFORM", +# "EJENDOMSKATE", +# "EJKAT20", +# "OVERDRAG", +# "VURDERING", +# "URBANGRAD", +# "UDGTYP", +# "KURTYP", +# "OPGOER", +# "UDINDLÅN", +# "LØBETID1", +# "RENTFIX1", +# "LAANSTR", +# "RENTFIX", +# "LAANSTRREPO", +# "INSTITYPE", +# "PAPIR", +# "KUPON", +# "LØBETID", +# "UDSTEDSEKTOR", +# "INVSEKTOR", +# "VÆRDIAN", +# "TYPREAL", +# "LØBETID3", +# "LØBETID2", +# "KUPON2", +# "UDSTED", +# "DAEKOBL", +# "DATAT", +# "ISNINAVN", +# "UDSTEDBRANC", +# "HOLBRANC", +# "ISIN", +# "UAKT", +# "OPT", +# "HOVED1", +# "KUPON1", +# "UDSTLAND", +# "INVESTOR", +# "INVEST1", +# "UDSTLAND2", +# "UDLKAT", +# "VAERDI1", +# "INVESTLAND", +# "TRANSAKT1", +# "DIMENSION", +# "KORTYPE", +# "PRIVATERHVERV", +# "KORTTEK", +# "MISBRUG2", +# "ANVSTED", +# "KORTUDSTED", +# "ENHED1", +# "HAEVIND", +# "BETJEN", +# "RET", +# "GEODAEK", +# "KREDIT", +# "INIT", +# "VISITATION", +# "YDTYPDETAL", +# "HERKOMST1", +# "BERET", +# "MORUD", +# "FARUD", +# "DAGPENGERET", +# "EKSISTENS", +# "UDDKOMB", +# "SOCIALSTATUS", +# "UGER", +# "BARNFAM", +# "FORAELDREDAGPENGE", +# "MORUDD", +# "FARUDD", +# "FORAELDREUDD", +# "MODTAG1", +# "PENSIONSTATUS", +# "LTIMER", +# "FORAN", +# "ANBRINGELSE", +# "ADMKOM", +# "ANBRINGAARSAG", +# "INDSATSER", +# "UNDERRETERE", +# "UNDERRET", +# "AFFALDSOPR", +# "AKTI", +# "AKTP", +# "VENTETIDGARANTI", +# "MYNDIGHEDSKOM", +# "AFSLUTSTATUS", +# "BEBOSTAT", +# "HERKAMS", +# "OPHOLD2", +# "OVERNAT", +# "MLGRP", +# "MND", +# "SERVYD", +# "HJEMBESOEG", +# "TIMEUGE", +# "KONAMS", +# "OVERTRÆD", +# "ANMSIGT", +# "AFGØRELSE", +# "STRAFLANG", +# "VARTILBAGE", +# "STRAFART", +# "OVER", +# "OVER1", +# "STRAFART1", +# "OVER2", +# "STRAFART2", +# "RECHEN", +# "TIDLDOM", +# "OVERNAT1", +# "FDOMALD", +# "LOVOV", +# "AVFFS", +# "FRISTRAF", +# "ADOM", +# "AFSLUT", +# "BOPDK", +# "AFSAVN", +# "SPORG", +# "SVAR", +# "KOAL", +# "SVAERHED1", +# "INDKOMGRP", +# "HFUIGANG", +# "HFUDD2", +# "INDIKATOR1", +# "UDDSTAT", +# "FORUDD1", +# "FORIND", +# "FORBESK", +# "GRUNDSKOL", +# "GRUNDBEL", +# "DKMAT", +# "IETYPE", +# "STATUSVID", +# "GRUNDKAR", +# "FSTATUS", +# "OMRÅDE1", +# "KLASSE", +# "SKTPE", +# "ELEV", +# "UDDDL", +# "UDDFORM", +# "HOMR", +# "UDVEKSLING", +# "OPVAR", +# "INSTI", +# "AFGAARG", +# "AFGKLAS", +# "AFGREG", +# "STATUSTID", +# "UDDANGROUP", +# "STATUSAFG", +# "ALDERLEV", +# "STARTUD", +# "STAT", +# "STARTALD", +# "FUDDOMR", +# "TIDSPUNKTER", +# "FORMEL", +# "UFORMEL", +# "UDDGRUND", +# "EFTERVIR", +# "ANSATTE", +# "INSTTYP", +# "KURSUS", +# "HOEJ_UDD_FAM", +# "AEKVI_FAM_INDKOMST", +# "PERS_INDK", +# "BOPLAND", +# "FUI01", +# "FUI08", +# "LEVRTYP", +# "VIDOMR", +# "PERSTYP", +# "FUI14", +# "SEKVID", +# "PERSONKAT", +# "FAGET", +# "DRIFT1", +# "PCTBNP", +# "UDGPOST", +# "VIDENHOVED", +# "SOCFORM", +# "AARVAERK", +# "OIN01", +# "INNO", +# "NYHEDSGRAD", +# "OIN03", +# "OIN02", +# "INNBRANCHE", +# "INNPRO", +# "INNPROCES", +# "INNSAM", +# "RESSOMR", +# "IPR1", +# "IPR2", +# "BRANCHEDB071019127", +# "BRANCHEDB0710TIL127", +# "FIRMSTR", +# "BRANCHEDB0710", +# "VIRKF1", +# "FIRMAALDER", +# "KONCERNSTOR", +# "KONCERN", +# "ARBSTRDK", +# "STØRRELSE", +# "VIRKSTR", +# "BRANCHEDB0721", +# "BESTPOST", +# "VFORM", +# "BESTMEDL", +# "FIRMASTAT", +# "VARIA", +# "STARTAAR", +# "VIRKTYP1", +# "LEVTID", +# "OMSÆTNING", +# "BESK", +# "BRANCHEREV2", +# "EMNER", +# "ANVEND", +# "AKTIVI", +# "REGNSKPOSTER", +# "FINAKT", +# "FINFORM", +# "UDFALD", +# "LAANEFIN", +# "BELØB", +# "OFFGRP", +# "FONDSTYPE", +# "BEVILLING2", +# "VIRKE", +# "MODTAG", +# "MODTAGER", +# "FAGOMR", +# "FONDSMIDLER", +# "UNDEROMRÅDE", +# "LANDE", +# "FIRMA", +# "FUNKTIONER", +# "JOBTYP", +# "DESTINA", +# "MOTIV", +# "BETYD", +# "FORTYP", +# "PRODUKT", +# "INVEST", +# "FUI6", +# "BEDRIFTSTAND", +# "KVARTIL", +# "BEDRIFTAARS", +# "BRUGSTYPE", +# "PRODGREN1", +# "REGNP", +# "REGNH", +# "KAPIT", +# "KORNART", +# "AREALSTOR", +# "BEDRIFT", +# "AREAL1", +# "UDBEDRIFT", +# "BDFALDER", +# "BEDRIFTSTR", +# "FORP", +# "BESKLAND", +# "PRAETEK", +# "UDALDER", +# "AFGRØDE", +# "AREALAFG", +# "OMR2", +# "SORT", +# "TRE", +# "KULT", +# "DYR", +# "BESAET", +# "HUSDYRTYPE", +# "DYRKAT", +# "OPRIND", +# "AK", +# "STRUK", +# "PROD", +# "VÆKST", +# "AREAL2", +# "FODER2", +# "VANDTY", +# "FODER1", +# "FODER", +# "STOFTYPE", +# "MÅLEENHED", +# "PESTICIDGR", +# "PESTICIDTYPE", +# "BEVOKSNING", +# "TRAESORT", +# "FISKFAR", +# "LAENG", +# "TONNAGE", +# "FANGST", +# "LANDING1", +# "FISK", +# "FARLAENGD", +# "ANLAEG", +# "FISKSKAL", +# "RÅSTOFTYPE", +# "VARGR6", +# "VARGR2", +# "OMSTYPE", +# "HOVEDGRP", +# "MARKED1", +# "STANDGRP", +# "BYGFASE", +# "BYGHERRE", +# "AAR", +# "BYGGESAG", +# "ÅR", +# "ARBART", +# "AREALINT", +# "AREALTYPE", +# "OPVARM", +# "TAGMAT", +# "YDREMAT", +# "HINDEKS", +# "DINDEKS", +# "BOLTYP", +# "OVERNATF", +# "NATION1", +# "KAPACITET", +# "SEG", +# "CERT", +# "FREMÅR", +# "FREMMD", +# "KAPMEDIE", +# "FARVAND", +# "TRANSMID", +# "RAPINST", +# "SEKKORNAT", +# "SEKTOR2", +# "RENTEFIX1", +# "FORMAAL1", +# "RENTE", +# "RENTEREF", +# "AFDRAG", +# "RENTETYPE", +# "EJENKATNAT", +# "DISAGGBALPOST", +# "AGGBALPOST", +# "AKTTYP", +# "EGENSEKTOR", +# "BETALFRIST", +# "SPECNAT", +# "INSTITUTTYPE", +# "NYUD", +# "BALPOSTNAT1", +# "INVESTFOND", +# "HOVEDKAT", +# "FORVALT", +# "RISIKO", +# "VARDIPAP", +# "UDSTEDKAT", +# "VIRKTYPNB", +# "INVESTNAT", +# "MARKVAERDI", +# "MEDIER", +# "OMSEKS", +# "BEDØMMELSE", +# "FORLØB", +# "AARSAG", +# "OPG", +# "PAAFOR", +# "BILTYPE", +# "REGBIL", +# "BILSEG", +# "DRIV", +# "BRUG", +# "ENERGI", +# "KM", +# "KOEBMOENS", +# "KOEBTYPE", +# "BOL", +# "RAADMOENS", +# "BESTAND", +# "SOMKOM", +# "EGEN", +# "BESTANDDEL", +# "TVAEGT", +# "AKSLER", +# "SIDDE", +# "TOG", +# "VOGN2", +# "SKIBTYPE", +# "SKIBREG", +# "BT", +# "VEJSTR", +# "VEJTYPE", +# "TRANSPORT", +# "BANE", +# "FLAG", +# "HAVN", +# "LUFTHAVN", +# "FLYVNING", +# "BANEL", +# "ROR", +# "SDGSERVICE", +# "BANES", +# "FÆRGE", +# "PASSAGER", +# "PÅSTIG1", +# "AFSTIG1", +# "DESTI", +# "REJSE", +# "KØRART", +# "TYPEVÆGT", +# "BILALDER", +# "TURKM", +# "VOGN", +# "LÆS", +# "GODS", +# "PÅREGION", +# "AFREGION", +# "LASTTYPE", +# "REG", +# "VOGN1", +# "START1", +# "SLUT1", +# "PÅLAND", +# "AFLAND", +# "LAST", +# "TRANSPORT1", +# "UHELDA", +# "UHELDSIT", +# "BYLAND", +# "HAST", +# "KLOK", +# "UGE", +# "MODPART", +# "TRANSINV", +# "UHELD", +# "SKADE", +# "PERSART", +# "GADEVEJ", +# "IUDENFOR", +# "SPIRIT", +# "INDBLAND", +# "KALDER", +# "ALCO", +# "INDBERET", +# "SKADEDIAG", +# "PKATEGORI", +# "UTYPE", +# "OMFANG", +# "MUSEER", +# "AFDLING", +# "AKTIVITET", +# "BESØGSTYPE", +# "ALDERK", +# "BESØG", +# "GENRE", +# "ADGANG", +# "ZOOKAT", +# "ZOO", +# "BYGTYP", +# "ANKAT", +# "ARKIV", +# "SAMLING", +# "OPGOER1", +# "MATER", +# "MATYPELEK", +# "UDLÅNSSTED", +# "AFSTANDBIB", +# "DIGITTJE", +# "BIB2", +# "KILD", +# "PLACERING", +# "LAESINTERVAL", +# "UDGIVFREK", +# "BOGER", +# "GEOOMR", +# "MEDIE", +# "BOGTYPE", +# "UDGAVE", +# "SPROG", +# "OVERSAT", +# "BTYPE", +# "OPLAG1", +# "FORMAT", +# "HOVEDGENRE", +# "UDGIVELSESSPROG", +# "RELATION", +# "INSP", +# "LAESFREK", +# "SADER", +# "BIOGRAF", +# "BIO", +# "NATION2", +# "BIOSTOR", +# "TYPMAL", +# "URPRIM", +# "FILMKAT", +# "CENSUR", +# "SPILLEUGE", +# "KULTUR", +# "LOKATION", +# "FINANSTYPE", +# "INDTTYPE", +# "TEATTYP", +# "PUBGRUP", +# "SCENE", +# "TEATER", +# "MGK", +# "ARBREG", +# "OEKNOGL", +# "KUNSTART", +# "SOCIALSAM", +# "MUSIKSAM", +# "DISTRIB", +# "RETTIGHED", +# "MUSVÆRK", +# "KONCERTARRANGØR", +# "KONCERTSTØRRELSE", +# "ARRANGEOR", +# "BRANCHEKULT", +# "UDDTYPE", +# "CL_REGION", +# "MESTER", +# "IDRAET", +# "MEDALJE", +# "DICIPLIN", +# "PRÆSTATION", +# "RELATIV", +# "RANG", +# "KØNALDER", +# "DELTAG1", +# "TIDBRUG", +# "ORGAN1", +# "FORBACK", +# "SPORTS", +# "TILSKUER", +# "IDRATAKT", +# "STED", +# "IDRFAC", +# "ORGANISATION", +# "SENANV", +# "SENKOB", +# "UDSTYR", +# "ADFÆRD", +# "OVERV", +# "FORMAAL", +# "FORHAND", +# "BREDBAAND", +# "BREDHAST", +# "ANTALANDEL", +# "PRIVAT", +# "ANNONCERING", +# "FORBRUG", +# "TJEN1", +# "KUNSTOMR", +# "INDGRUND", +# "VINDKOMST", +# "KULTUREMNE", +# "UDDINST", +# "DIMMITEND", +# "LEDTYP", +# "INTNAT", +# "EFFEKTER", +# "KREATIVEERHVERV", +# "FINANSART", +# "STATSINSTITUITION", +# "KUBSBELI", +# "VIRKTYP2", +# "LANDTYP", +# "ARE1", +# "BR19A2", +# "ENERGI1", +# "PVARMEKILDE", +# "AARSFORBRUG", +# "PRISDEFINITION", +# "ENERGIENHED", +# "TILANV", +# "TILGANG", +# "MULT", +# "ANVEND1", +# "EMTYPE8", +# "OVERPOST", +# "OPPRINCIP", +# "ENERGIKILDE", +# "ANVENDTYPE", +# "UDLEDBRANCHE", +# "UDLEDLAND", +# "BRANCHEAFTRYK1", +# "BEHANDLING", +# "AFFFRAK", +# "FARLIG", +# "VANDTYP", +# "INDKAT", +# "UDL", +# "MFORMAAL", +# "KATEGORI", +# "MILJOKAT", +# "SKATTEART", +# "BALPOST", +# "OEKOSTATUS", +# "VARTYP", +# "MÆNGDE6", +# "KUNDEGRP" +# ) +# +# +# +# +# +# "TILKOMMUNE", +# "FRAKOMMUNE", diff --git a/data-raw/dkstat_groups.R b/data-raw/dkstat_groups.R new file mode 100644 index 0000000..04f53dd --- /dev/null +++ b/data-raw/dkstat_groups.R @@ -0,0 +1,164 @@ +# dkstat_groups.R +# This file is found in +# https://github.com/rOpenGov/dkstat/blob/main/data-raw/dkstat_groups.R and +# https://github.com/rOpenGov/geodk/blob/main/data-raw/dkstat_groups.R. If you +# change anything in either file, please remember to change in both places. + +## Municipality groups - KOMGRP +create_groups <- function(x) { + + levels <- x |> + dplyr::filter(NIVEAU == 1) |> + unique() |> + dplyr::pull(name) + + id <- 0 + groups <- numeric(nrow(x)) + + for (i in 1:nrow(x)) { + if (x$NIVEAU[i] == 1) { + id <- id + 1 + } + + groups[i] <- id + } + + x$group <- groups + x$level <- levels[groups] + return(x) +} + +# I have contacted the consultant in charge of the classification and requested +# a download-link / api-access to not have to distribute the csv-file alongside +# the package source code. +# https://www.dst.dk/da/Statistik/dokumentation/nomenklaturer/kommunegrupper +komgrp <- readr::read_csv2("data-raw/komgrp.csv") |> + dplyr::select(KODE, NIVEAU, TITEL) |> + dplyr::mutate( + name = paste(KODE, TITEL) + ) |> + create_groups() |> + dplyr::group_by(level) |> + dplyr::filter(NIVEAU == 2) |> + dplyr::summarise( + list = list({ + values <- TITEL + names(values) <- paste(KODE, TITEL, sep = " ") + as.list(values) + }) + ) |> + tibble::deframe() + +usethis::use_data(komgrp, compress = "xz", overwrite = TRUE) + + +# Municipality groups with "Hele landet" as well +kom_omraade <- c( + "000 Hele landet", + "1 Hovedstadskommuner", + "2 Storbykommuner", + "3 Provinsbykommuner", + "4 Oplandskommuner", + "5 Landkommuner", + "101 København", + "147 Frederiksberg", + "155 Dragør", + "185 Tårnby", + "165 Albertslund", + "151 Ballerup", + "153 Brøndby", + "157 Gentofte", + "159 Gladsaxe", + "161 Glostrup", + "163 Herlev", + "167 Hvidovre", + "169 Høje-Taastrup", + "183 Ishøj", + "173 Lyngby-Taarbæk", + "175 Rødovre", + "187 Vallensbæk", + "201 Allerød", + "240 Egedal", + "210 Fredensborg", + "250 Frederikssund", + "190 Furesø", + "270 Gribskov", + "260 Halsnæs", + "217 Helsingør", + "219 Hillerød", + "223 Hørsholm", + "230 Rudersdal", + "400 Bornholm", + "411 Christiansø", + "253 Greve", + "259 Køge", + "350 Lejre", + "265 Roskilde", + "269 Solrød", + "320 Faxe", + "376 Guldborgsund", + "316 Holbæk", + "326 Kalundborg", + "360 Lolland", + "370 Næstved", + "306 Odsherred", + "329 Ringsted", + "330 Slagelse", + "340 Sorø", + "336 Stevns", + "390 Vordingborg", + "420 Assens", + "430 Faaborg-Midtfyn", + "440 Kerteminde", + "482 Langeland", + "410 Middelfart", + "480 Nordfyns", + "450 Nyborg", + "461 Odense", + "479 Svendborg", + "492 Ærø", + "530 Billund", + "561 Esbjerg", + "563 Fanø", + "607 Fredericia", + "510 Haderslev", + "621 Kolding", + "540 Sønderborg", + "550 Tønder", + "573 Varde", + "575 Vejen", + "630 Vejle", + "580 Aabenraa", + "710 Favrskov", + "766 Hedensted", + "615 Horsens", + "707 Norddjurs", + "727 Odder", + "730 Randers", + "741 Samsø", + "740 Silkeborg", + "746 Skanderborg", + "706 Syddjurs", + "751 Aarhus", + "657 Herning", + "661 Holstebro", + "756 Ikast-Brande", + "665 Lemvig", + "760 Ringkøbing-Skjern", + "779 Skive", + "671 Struer", + "791 Viborg", + "810 Brønderslev", + "813 Frederikshavn", + "860 Hjørring", + "849 Jammerbugt", + "825 Læsø", + "846 Mariagerfjord", + "773 Morsø", + "840 Rebild", + "787 Thisted", + "820 Vesthimmerlands", + "851 Aalborg" +) + +usethis::use_data(kom_omraade, compress = "xz", overwrite = TRUE) diff --git a/data-raw/komgrp.csv b/data-raw/komgrp.csv new file mode 100644 index 0000000..9c50d4a --- /dev/null +++ b/data-raw/komgrp.csv @@ -0,0 +1,104 @@ +SEKVENS;KODE;NIVEAU;TITEL;GENERELLE_NOTER;INKLUDERER;INKLUDERER_OGSÅ;EKSKLUDERER;PARAGRAF;MÅLEENHED +1;"1";1;Hovedstadskommuner;;;;;; +2;"101";2;København;;;;;; +3;"147";2;Frederiksberg;;;;;; +4;"151";2;Ballerup;;;;;; +5;"153";2;Brøndby;;;;;; +6;"155";2;Dragør;;;;;; +7;"157";2;Gentofte;;;;;; +8;"159";2;Gladsaxe;;;;;; +9;"161";2;Glostrup;;;;;; +10;"163";2;Herlev;;;;;; +11;"165";2;Albertslund;;;;;; +12;"167";2;Hvidovre;;;;;; +13;"169";2;Høje-Taastrup;;;;;; +14;"173";2;Lyngby-Taarbæk;;;;;; +15;"175";2;Rødovre;;;;;; +16;"183";2;Ishøj;;;;;; +17;"185";2;Tårnby;;;;;; +18;"187";2;Vallensbæk;;;;;; +19;"190";2;Furesø;;;;;; +20;"201";2;Allerød;;;;;; +21;"223";2;Hørsholm;;;;;; +22;"230";2;Rudersdal;;;;;; +23;"240";2;Egedal;;;;;; +24;"253";2;Greve;;;;;; +25;"269";2;Solrød;;;;;; +26;"2";1;Storbykommuner;;;;;; +27;"461";2;Odense;;;;;; +28;"751";2;Aarhus;;;;;; +29;"851";2;Aalborg;;;;;; +30;"3";1;Provinsbykommuner;;;;;; +31;"217";2;Helsingør;;;;;; +32;"219";2;Hillerød;;;;;; +33;"259";2;Køge;;;;;; +34;"265";2;Roskilde;;;;;; +35;"330";2;Slagelse;;;;;; +36;"370";2;Næstved;;;;;; +37;"561";2;Esbjerg;;;;;; +38;"607";2;Fredericia;;;;;; +39;"615";2;Horsens;;;;;; +40;"621";2;Kolding;;;;;; +41;"630";2;Vejle;;;;;; +42;"657";2;Herning;;;;;; +43;"661";2;Holstebro;;;;;; +44;"730";2;Randers;;;;;; +45;"740";2;Silkeborg;;;;;; +46;"791";2;Viborg;;;;;; +47;"4";1;Oplandskommuner;;;;;; +48;"210";2;Fredensborg;;;;;; +49;"250";2;Frederikssund;;;;;; +50;"260";2;Halsnæs;;;;;; +51;"270";2;Gribskov;;;;;; +52;"316";2;Holbæk;;;;;; +53;"320";2;Faxe;;;;;; +54;"329";2;Ringsted;;;;;; +55;"336";2;Stevns;;;;;; +56;"340";2;Sorø;;;;;; +57;"350";2;Lejre;;;;;; +58;"410";2;Middelfart;;;;;; +59;"420";2;Assens;;;;;; +60;"430";2;Faaborg-Midtfyn;;;;;; +61;"440";2;Kerteminde;;;;;; +62;"450";2;Nyborg;;;;;; +63;"480";2;Nordfyns;;;;;; +64;"575";2;Vejen;;;;;; +65;"706";2;Syddjurs;;;;;; +66;"710";2;Favrskov;;;;;; +67;"727";2;Odder;;;;;; +68;"746";2;Skanderborg;;;;;; +69;"756";2;Ikast-Brande;;;;;; +70;"766";2;Hedensted;;;;;; +71;"840";2;Rebild;;;;;; +72;"5";1;Landkommuner;;;;;; +73;"306";2;Odsherred;;;;;; +74;"326";2;Kalundborg;;;;;; +75;"360";2;Lolland;;;;;; +76;"376";2;Guldborgsund;;;;;; +77;"390";2;Vordingborg;;;;;; +78;"400";2;Bornholm;;;;;; +79;"479";2;Svendborg;;;;;; +80;"482";2;Langeland;;;;;; +81;"492";2;Ærø;;;;;; +82;"510";2;Haderslev;;;;;; +83;"530";2;Billund;;;;;; +84;"540";2;Sønderborg;;;;;; +85;"550";2;Tønder;;;;;; +86;"563";2;Fanø;;;;;; +87;"573";2;Varde;;;;;; +88;"580";2;Aabenraa;;;;;; +89;"665";2;Lemvig;;;;;; +90;"671";2;Struer;;;;;; +91;"707";2;Norddjurs;;;;;; +92;"741";2;Samsø;;;;;; +93;"760";2;Ringkøbing-Skjern;;;;;; +94;"773";2;Morsø;;;;;; +95;"779";2;Skive;;;;;; +96;"787";2;Thisted;;;;;; +97;"810";2;Brønderslev;;;;;; +98;"813";2;Frederikshavn;;;;;; +99;"820";2;Vesthimmerlands;;;;;; +100;"825";2;Læsø;;;;;; +101;"846";2;Mariagerfjord;;;;;; +102;"849";2;Jammerbugt;;;;;; +103;"860";2;Hjørring;;;;;; diff --git a/data/kom_omraade.rda b/data/kom_omraade.rda new file mode 100644 index 0000000000000000000000000000000000000000..aa9411dabba7a8931fe1b5221fc4abf752575a78 GIT binary patch literal 1108 zcmV-a1grb~H+ooF0004LBHlIv03iV!0000G&sfah2(|vQ&2UKVgRpfkl( ztnn6!$!Kl^VMGIvukwO8Frd72I!zzinxljuO|VtFVs~Vl#CNd+BD#mC*xm2eC{$*I?Skz@ej3JG zf?6TGy^GKIPygT49ZDgx zPlv$#IoL!^5pPDljcuL6nwdF`7^2M@85na_#W-9O4jMXFWf!|6c}J<6=!A8e)Nu|N zyM~xCuzMe-s-4xQ=K0cyz7fCk){v`|HSQjk{q~t%=*U*%i7c^am>LY*Y6I-$^id&R zMVk>VwOQg6;Mg^L_`d#L6%I#2M0NJ{8nH3F0SbY81@l#)V!fJ(l$6lYEpZ7yha$PP zYHl0AlL*U_fJqRj!-&Sh74FL>TeuFdAVXH`zpRm)Md1_h<81?#>EgUC9v6LjAy*^z z2)7LE?gNKabbXGghhH!SQPvt(L*Yxw`G@|rFnd+8wPlm+bKdUK+lb2nI0+7%aKsi_ zP6jR0^2tJI$+L-z+G7t{k4=Bud)kZ|f8`uAGgy0K8gW)^p?*5rzp1gH@0l?GadIcVD38loex2IhXF=&po}4l7z#nXAEhp?t0^gl^s-@q>+{SZ_Y+$rYLElQTEKh#R#bj@sp(aC5cEPV_DbtA>*p@aI><)11 z@fzkNB<+2cMD&O{%R=Oi7llchQs`H0f_ChL728fu#@y-ZDXcFq6aZTSF6-fecKH>lX0000{9Y}-# a0j&tP5dZ*4BIe6JFb#_W000000a;pOqzbbD literal 0 HcmV?d00001 diff --git a/data/komgrp.rda b/data/komgrp.rda new file mode 100644 index 0000000000000000000000000000000000000000..39cc39a65608bdaaa31b48ede3db27a5cd650f2c GIT binary patch literal 1544 zcmV+j2KV{>H+ooF0004LBHlIv03iV!0000G&sfah5`G2CT>vQ&2UKVgRpfkl( ztnn6!$!Kl^VMGIvukwO8Frd72I!zzJS;X}}{eW)pRyUeNE%yrIZKbq>w{Pkc33nhS zZZMtdTK1f#t^VIugU6dWfBY-eL*+T=MDJLU>;`1!1dC%DzRz?Y1lGvk@7Qe}W0*9% zrz(K0cX^&73GVt|??*n6x83o=AI6`9%y+Y2F!Rd0NbQP*=lH%5iy0A4x z{GWoL!ItGEhdM$}U`D&r-D^PX@C`4*JrbcSgy6uDcB`xpgO)j~I)Oy2a!W6U&2)cA^gTD|h(Y>wbs@4E?g}bqpKj`6V(7A$x+l%>RZq7ghkAxYP)t78OotR0 zKOX%!@DYYUu?rMPzj=G*-}3;kc#H>lF;c&afZ;_i^mc}u6vs|46Tl;u<4+JV9UCSP zg1>4BFqk4txBR77-eyPSUx7^gDE4qMLnE-xn-g;iY^JnT1A>WsA+PWrUBkYxdF^*$ zACCw6H}5Xl)zu#Q{`}!aKZ79WiHSG0LSYhx-$0VRz*2cYp4u25C)o*vap~->M;^T~ zpV$c6*^mFHe@qHQc;Xi2#ZuSXWBfbyk<9 z7`sT#sAUf8#sg{yL|kVdU%9?%(J8lMPfOw4CBy6>VM8DnE2qWriGz%*4SiHKB;w}C zpH|56U}l+QD5jWuZ3-o&mLS0+v}5Uyl?R(t=ikVb16A@GIZ`6w%^Tb`9C4#)0(F-! zVNf#L>qx;EF0!YCV^^v>mzBD=uXKfZJ+P^vWs*|p!jPjt!nQoHBmheo6>H`FWL{1q!|Z7|Mk4%4Vcp<<(=|PB@8Nx`MF~ zEQtf6BFn1CG9Y9Y@bo_+fV_R#2TE8FB2_^}=fjR}B;Xed96aYA>{^Dh)I5AJbyabg zVOECRbT%im^~P6h4VJ+h9}+rtcPqzai6uqfcApywC&OO&N)y*ugSg8!Z~%IIL-O00cq#!jk(e*+TTDImx)wsNMdCPY9VaVK(*< z->k;zdfo-xSSD27lwcT;^;yPih*d957m$tv-O^w4Rk_?4dBuct4wpnA$pMQeHEHwn z0&=3t)hRiW)iz*)81xi1Z@^~00k!PRKQ`k=w11Ed+raIEn*Q&=7A9Gpf&7TFih|13 zl^!K4_(U7PiRkOtYuU12P`z>4sGGo!(xzD(4Ox{c>mdKpMW;({6FIQ|Lm50Dm3+G}fr+X%0f=78iv!x;(CcGmY&+2SE4ugs)*$x5+V< z@sNtyBK}=bolHknLaOPcm$|KD0&iJBVFf+;)&i*WgiTnIO>L+-lq#RND*`)Nxewr~ z(2AuxTuY?0w+@#K?4IDlfPTEJpm3ZRD_eDtBLnU<^(aL_?gw4Rg#Gi=!f31YFWUf^ zE!MwDH0M9GZcd)ztg^V!aeG@qt=5)UcI&KlumqgEk4l(!5vCnuv;jWG9%K!t@|9#H zRb;qo+9ZAwJ`}ddz;1}=-V*IA2)^-v_ZO5{dMqN2Kv$?aKFSgdTfl&Ms;a%YWa1ff zzD6kevvb+xQnF*V&w4zW?oZLcUJU4sFr4}A7E1D>7t*US(sj>TVCRd?S=K|iimG`q zIINa3+YeyIaIV6adzD|7Og$tj1t*n-#BNp48MeVIay_|FdY$5kLN;#9DJNZ;QdO0n uIsygj-SC+Ok64SP0001E3ZOIq0pkn*Bme*{WE90dFb#_W000000a;pn@ai4_ literal 0 HcmV?d00001 diff --git a/dkstat.Rproj b/dkstat.Rproj index 9539a17..39b135b 100644 --- a/dkstat.Rproj +++ b/dkstat.Rproj @@ -1,5 +1,5 @@ Version: 1.0 -ProjectId: 0fa5e426-8c7c-454b-b5f9-7d4f91b882c1 +ProjectId: 2f8c1cc5-d2d5-4418-86e7-a3dc41bb0046 RestoreWorkspace: Default SaveWorkspace: Default diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/refs.bib b/vignettes/refs.bib new file mode 100644 index 0000000..00e1ba0 --- /dev/null +++ b/vignettes/refs.bib @@ -0,0 +1,11 @@ +@book{adv-r, + title = "Advanced R, second edition", + author = "Wickham, Hadley", + publisher = "CRC Press", + series = "Chapman \& Hall/CRC The R Series", + edition = 2, + month = may, + year = 2019, + address = "Boca Raton, FL", + language = "en" +} diff --git a/vignettes/tech-specs-for-geodk.Rmd b/vignettes/tech-specs-for-geodk.Rmd new file mode 100644 index 0000000..ce6b343 --- /dev/null +++ b/vignettes/tech-specs-for-geodk.Rmd @@ -0,0 +1,101 @@ +--- +title: "Technical specification for intergration with {geodk}" +output: rmarkdown::html_vignette +bibliography: refs.bib +vignette: > + %\VignetteIndexEntry{tech-specs-for-geodk} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup, include = FALSE} +library(dkstat) +library(geodk) +library(tidyverse) +# library(ggflowchart) +``` + +# What is this? + +This documents the technical specification for the integration between `{dkstat}` and `{geodk}`. It can be found on this page and in [the `{geodk}` documentation](https://ropengov.github.io/geodk/articles/tech-specs-for-dkstat.html). `vignette("tech-specs-for-dkstat", package = "geodk")`. + +## Why would you want to read this? + +I honestly don't know. This document is written mostly for me [(Aleksander)](https://aleksanderbl.dk) and contributors to use as a reference when maintaining this integration. If you have any interest in the inner workings of how these two packages interact, then please do read on. + +# Integration usage + +A thorough usage guide can be found in `vignette("geodk", package = "dkstat")`, but below I will provide a technical walkthrough of the integration. + +## Main goal + +The main goal of the integration between `{dkstat}` and `{geodk}` is to be able to run the following code and have meaningful geographic information added to the statistics. + +```{r main-goal, eval = FALSE} +dkstat::dst_get_all_data("laby04") |> + geodk::geodk_enrich() # This function name is still debatable. +``` + +## Problem description + +When accessing data from a table, e.g. "laby04" there is no obvious way to know what column is geographic. + +```{r} +dkstat::dst_get_all_data("laby04") |> + distinct(OMRÅDE, .keep_all = TRUE) |> + tail() +``` + +When looking at the above tail, I (and probably you, as well) can recognise that the `OMRÅDE` column is the geographic one. + +### Tables with multiple geographic levels + +Some tables, e.g. "laby04" has multiple geographic levels. This table has a grouping of municipalities and then the individual municipalities. To ensure that the individuals *and* groups are enriched properly, we have to take the different levels into account in the method. + +# S3 methods + +Below you can find the description of each S3-class that is used (/abused) to enrich the statistical data with geographic information. It is sectioned by the geographic grouping of the dataset. Before we dive into the specific classes, I will first outline the general idea. For more information on the specific terminology used, please consult @adv-r. + +## Classes + +Each type of geographic variable has its own S3 class. The class is determined by what observations is included in the variable. The class-assignment is done by a series of custom class-constructors called `new_dkstat_*()`. One example is `new_dkstat_KOMGRP()` which assigns the S3 class `dkstat_KOMGRP` to a dataset. The class is assigned "after the fact", as Wickham calls it, ensuring that the usual behaviour of a data.frame is preserved for all the functions that don't know about these special classes (e.g. the `{dplyr}` functions). + +## Method dispatch + +The S3 generic can be found in `geodk::geodk_enrich()`. The individual methods also live in `{geodk}`. This is to not take on `{geodk}` as a dependency in `{dkstat}`. The S3 method for the municipality group (KOMGRP) from above is called `geodk_enrich.dkstat_KOMGRP()`. Please [open an issue](https://github.com/rOpenGov/geodk/issues) if you would like to help add a method from another data source. + +# Custom classes + +## Municipality groups + +The municipality grouping that are specified by Statistics Denmark are described [on this website](https://www.dst.dk/da/Statistik/dokumentation/nomenklaturer/kommunegrupper). This grouping includes both the individual municipality and five groupings. Take a look at the link if you would like to learn more. In the `{geodk}` backend I have created a list containing all the municipality names with both Statistics Denmark-naming and geodk-naming. In addition to that, the list is ordered by the municipality grouping. + +This grouping is assigned the `dkstat_KOMGRP` class in addition to the `data.frame` class it already has. + +The method for `dkstat_KOMGRP` first filters the groupings from the individual municipalities. A list of the individual municipalities and groupings, along with their specific ids is stored in `{geodk}`. It is not exported to the user. + +After filtering, it assigns the individual municipality geometries. The grouping geometries are also assigned as well as a column indicating the geographic nature of the observation - Is it a overall grouping or an individual municipality? + +The municipalities that make up the groupings are split per group and run through `sf::st_union()` to be returned as a `sf` geometry per group. + +# References + + + + + + + + + + + + + From dba340d3e539947f5f8c7528de8e22d2e55dc0e7 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Thu, 13 Feb 2025 13:06:42 +0100 Subject: [PATCH 04/28] Update renv snapshot --- renv.lock | 954 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 942 insertions(+), 12 deletions(-) diff --git a/renv.lock b/renv.lock index 7967920..8662fa9 100644 --- a/renv.lock +++ b/renv.lock @@ -21,6 +21,50 @@ ] }, "Packages": { + "BH": { + "Package": "BH", + "Version": "1.87.0-1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "468d9a03ba57f22ebde50060fd13ba9f" + }, + "DBI": { + "Package": "DBI", + "Version": "1.2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "065ae649b05f1ff66bb0c793107508f5" + }, + "KernSmooth": { + "Package": "KernSmooth", + "Version": "2.23-24", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "stats" + ], + "Hash": "9f33a1ee37bbe8919eb2ec4b9f2473a5" + }, + "MASS": { + "Package": "MASS", + "Version": "7.3-61", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "methods", + "stats", + "utils" + ], + "Hash": "0cafd6f0500e5deba33be22c46bf6055" + }, "Matrix": { "Package": "Matrix", "Version": "1.7-1", @@ -48,6 +92,16 @@ ], "Hash": "470851b6d5d0ac559e9d01bb352b4021" }, + "RColorBrewer": { + "Package": "RColorBrewer", + "Version": "1.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "45f0398006e83a5b10b72a90663d8d8c" + }, "Rcpp": { "Package": "Rcpp", "Version": "1.0.14", @@ -66,6 +120,18 @@ "Repository": "CRAN", "Hash": "46da3912f69e3e6258a033802c4af32e" }, + "anytime": { + "Package": "anytime", + "Version": "0.3.11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "BH", + "R", + "Rcpp" + ], + "Hash": "a1db66ce27bcfb58cb67ad4e04d48b79" + }, "askpass": { "Package": "askpass", "Version": "1.2.1", @@ -98,6 +164,16 @@ ], "Hash": "5d0f7d92f3b12c79530eba0f60456e76" }, + "backports": { + "Package": "backports", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "e1e1b9d75c37401117b636b7ae50827a" + }, "base64enc": { "Package": "base64enc", "Version": "0.1-3", @@ -108,6 +184,43 @@ ], "Hash": "543776ae6848fde2f48ff3816d0628bc" }, + "bit": { + "Package": "bit", + "Version": "4.5.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "f89f074e0e49bf1dbe3eba0a15a91476" + }, + "bit64": { + "Package": "bit64", + "Version": "4.6.0-1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bit", + "graphics", + "methods", + "stats", + "utils" + ], + "Hash": "4f572fbc586294afff277db583b9060f" + }, + "blob": { + "Package": "blob", + "Version": "1.2.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods", + "rlang", + "vctrs" + ], + "Hash": "40415719b5a479b87949f3aa0aee737c" + }, "brew": { "Package": "brew", "Version": "1.0-10", @@ -125,6 +238,26 @@ ], "Hash": "c1ee497a6d999947c2c224ae46799b1a" }, + "broom": { + "Package": "broom", + "Version": "1.0.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "backports", + "dplyr", + "generics", + "glue", + "lifecycle", + "purrr", + "rlang", + "stringr", + "tibble", + "tidyr" + ], + "Hash": "8fcc818f3b9887aebaf206f141437cc9" + }, "bslib": { "Package": "bslib", "Version": "0.8.0", @@ -171,6 +304,47 @@ ], "Hash": "d7e13f49c19103ece9e58ad2d83a7354" }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "rematch", + "tibble" + ], + "Hash": "f61dbaec772ccd2e17705c1e872e9e7c" + }, + "class": { + "Package": "class", + "Version": "7.3-22", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "MASS", + "R", + "stats", + "utils" + ], + "Hash": "f91f6b29f38b8c280f2b9477787d4bb2" + }, + "classInt": { + "Package": "classInt", + "Version": "0.4-11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "KernSmooth", + "R", + "class", + "e1071", + "grDevices", + "graphics", + "stats" + ], + "Hash": "f2af70314a63d7f025ae668f08bd933a" + }, "cli": { "Package": "cli", "Version": "3.6.3", @@ -199,6 +373,20 @@ "Repository": "CRAN", "Hash": "96c01552bfd5661b9bbdefbc762f4bcd" }, + "colorspace": { + "Package": "colorspace", + "Version": "2.1-1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "methods", + "stats" + ], + "Hash": "d954cb1c57e8d8b756165d7ba18aa55a" + }, "commonmark": { "Package": "commonmark", "Version": "1.9.2", @@ -206,6 +394,19 @@ "Repository": "CRAN", "Hash": "14eb0596f987c71535d07c3aff814742" }, + "conflicted": { + "Package": "conflicted", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "memoise", + "rlang" + ], + "Hash": "bb097fccb22d156624fd07cd2894ddb6" + }, "cpp11": { "Package": "cpp11", "Version": "0.5.1", @@ -252,6 +453,66 @@ ], "Hash": "8dd23d308c751efdf675124aad4bf5d7" }, + "data.table": { + "Package": "data.table", + "Version": "1.16.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "38bbf05fc2503143db4c734a7e5cab66" + }, + "dawaR": { + "Package": "dawaR", + "Version": "0.2.7.9000", + "Source": "Repository", + "Repository": "https://aleksanderbl29.r-universe.dev", + "RemoteUrl": "https://github.com/aleksanderbl29/dawaR", + "RemoteRef": "universe-release", + "RemoteSha": "c81e0444a57c82fbc5f41baa6b10713c6bcaa83f", + "Requirements": [ + "R", + "cli", + "curl", + "httr2", + "memoise", + "rlang", + "sf", + "tidyRSS", + "utils" + ], + "Hash": "92c45684111c462b713c792fa9e3265e" + }, + "dbplyr": { + "Package": "dbplyr", + "Version": "2.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "DBI", + "R", + "R6", + "blob", + "cli", + "dplyr", + "glue", + "lifecycle", + "magrittr", + "methods", + "pillar", + "purrr", + "rlang", + "tibble", + "tidyr", + "tidyselect", + "utils", + "vctrs", + "withr" + ], + "Hash": "39b2e002522bfd258039ee4e889e0fd1" + }, "desc": { "Package": "desc", "Version": "1.4.3", @@ -368,6 +629,41 @@ ], "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" }, + "dtplyr": { + "Package": "dtplyr", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "data.table", + "dplyr", + "glue", + "lifecycle", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ], + "Hash": "54ed3ea01b11e81a86544faaecfef8e2" + }, + "e1071": { + "Package": "e1071", + "Version": "1.7-16", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "class", + "grDevices", + "graphics", + "methods", + "proxy", + "stats", + "utils" + ], + "Hash": "27a09ca40266a1066d62ef5402dd51d6" + }, "ellipsis": { "Package": "ellipsis", "Version": "0.3.2", @@ -401,6 +697,13 @@ ], "Hash": "962174cf2aeb5b9eea581522286a911f" }, + "farver": { + "Package": "farver", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "680887028577f3fa2a81e410ed0d6e42" + }, "fastmap": { "Package": "fastmap", "Version": "1.2.0", @@ -420,6 +723,22 @@ ], "Hash": "bd1297f9b5b1fc1372d19e2c4cd82215" }, + "forcats": { + "Package": "forcats", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "tibble" + ], + "Hash": "1a0a9a3d5083d0d573c4214576f1e690" + }, "fs": { "Package": "fs", "Version": "1.6.5", @@ -431,6 +750,28 @@ ], "Hash": "7f48af39fa27711ea5fbd183b399920d" }, + "gargle": { + "Package": "gargle", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "fs", + "glue", + "httr", + "jsonlite", + "lifecycle", + "openssl", + "rappdirs", + "rlang", + "stats", + "utils", + "withr" + ], + "Hash": "fc0b272e5847c58cd5da9b20eedbd026" + }, "generics": { "Package": "generics", "Version": "0.1.3", @@ -442,6 +783,20 @@ ], "Hash": "15e9634c0fcd294799e9b2e929ed1b86" }, + "geodk": { + "Package": "geodk", + "Version": "0.0.0.9000", + "Source": "Repository", + "Repository": "rOpenGov", + "Requirements": [ + "R", + "dawaR", + "dplyr", + "ggplot2", + "rlang" + ], + "Hash": "a209fab6f9197c53a7a6979ab2945173" + }, "gert": { "Package": "gert", "Version": "2.1.4", @@ -457,6 +812,31 @@ ], "Hash": "ae855ad6d7be20dd7b05d43d25700398" }, + "ggplot2": { + "Package": "ggplot2", + "Version": "3.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "MASS", + "R", + "cli", + "glue", + "grDevices", + "grid", + "gtable", + "isoband", + "lifecycle", + "mgcv", + "rlang", + "scales", + "stats", + "tibble", + "vctrs", + "withr" + ], + "Hash": "44c6a2f8202d5b7e878ea274b1092426" + }, "gh": { "Package": "gh", "Version": "1.4.1", @@ -496,6 +876,96 @@ ], "Hash": "5899f1eaa825580172bb56c08266f37c" }, + "googledrive": { + "Package": "googledrive", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "gargle", + "glue", + "httr", + "jsonlite", + "lifecycle", + "magrittr", + "pillar", + "purrr", + "rlang", + "tibble", + "utils", + "uuid", + "vctrs", + "withr" + ], + "Hash": "e99641edef03e2a5e87f0a0b1fcc97f4" + }, + "googlesheets4": { + "Package": "googlesheets4", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cellranger", + "cli", + "curl", + "gargle", + "glue", + "googledrive", + "httr", + "ids", + "lifecycle", + "magrittr", + "methods", + "purrr", + "rematch2", + "rlang", + "tibble", + "utils", + "vctrs", + "withr" + ], + "Hash": "d6db1667059d027da730decdc214b959" + }, + "gtable": { + "Package": "gtable", + "Version": "0.3.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "grid", + "lifecycle", + "rlang", + "stats" + ], + "Hash": "de949855009e2d4d0e52a844e30617ae" + }, + "haven": { + "Package": "haven", + "Version": "2.5.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "cpp11", + "forcats", + "hms", + "lifecycle", + "methods", + "readr", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ], + "Hash": "9171f898db9d9c4c1b2c745adc2c1ef1" + }, "highr": { "Package": "highr", "Version": "0.11", @@ -507,6 +977,20 @@ ], "Hash": "d65ba49117ca223614f71b60d85b8ab7" }, + "hms": { + "Package": "hms", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "lifecycle", + "methods", + "pkgconfig", + "rlang", + "vctrs" + ], + "Hash": "b59377caa7ed00fa41808342002138f9" + }, "htmltools": { "Package": "htmltools", "Version": "0.5.8.1", @@ -589,6 +1073,17 @@ ], "Hash": "0f14199bbd820a9fca398f2df40994f1" }, + "ids": { + "Package": "ids", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "openssl", + "uuid" + ], + "Hash": "99df65cfef20e525ed38c3d2577f7190" + }, "ini": { "Package": "ini", "Version": "0.3.1", @@ -596,6 +1091,17 @@ "Repository": "CRAN", "Hash": "6154ec2223172bce8162d4153cda21f7" }, + "isoband": { + "Package": "isoband", + "Version": "0.2.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grid", + "utils" + ], + "Hash": "0080607b4a1a7b28979aecef976d8bc2" + }, "janeaustenr": { "Package": "janeaustenr", "Version": "1.0.0", @@ -642,6 +1148,17 @@ ], "Hash": "9fcb189926d93c636dea94fbe4f44480" }, + "labeling": { + "Package": "labeling", + "Version": "0.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "graphics", + "stats" + ], + "Hash": "b64ec208ac5bc1852b285f665d6368b3" + }, "later": { "Package": "later", "Version": "1.4.1", @@ -713,29 +1230,89 @@ "cachem", "rlang" ], - "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mgcv": { + "Package": "mgcv", + "Version": "1.9-1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "Matrix", + "R", + "graphics", + "methods", + "nlme", + "splines", + "stats", + "utils" + ], + "Hash": "110ee9d83b496279960e162ac97764ce" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "miniUI": { + "Package": "miniUI", + "Version": "0.1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "htmltools", + "shiny", + "utils" + ], + "Hash": "fec5f52652d60615fdb3957b3d74324a" + }, + "modelr": { + "Package": "modelr", + "Version": "0.1.11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "broom", + "magrittr", + "purrr", + "rlang", + "tibble", + "tidyr", + "tidyselect", + "vctrs" + ], + "Hash": "4f50122dc256b1b6996a4703fecea821" }, - "mime": { - "Package": "mime", - "Version": "0.12", + "munsell": { + "Package": "munsell", + "Version": "0.5.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ - "tools" + "colorspace", + "methods" ], - "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + "Hash": "4fd8900853b746af55b81fda99da7695" }, - "miniUI": { - "Package": "miniUI", - "Version": "0.1.1.1", + "nlme": { + "Package": "nlme", + "Version": "3.1-166", "Source": "Repository", "Repository": "CRAN", "Requirements": [ - "htmltools", - "shiny", + "R", + "graphics", + "lattice", + "stats", "utils" ], - "Hash": "fec5f52652d60615fdb3957b3d74324a" + "Hash": "ccbb8846be320b627e6aa2b4616a2ded" }, "openssl": { "Package": "openssl", @@ -883,6 +1460,20 @@ ], "Hash": "bffa126bf92987e677c12cfb5651fc1d" }, + "progress": { + "Package": "progress", + "Version": "1.2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "f4625e061cb2865f111b47ff163a5ca6" + }, "promises": { "Package": "promises", "Version": "1.3.2", @@ -899,6 +1490,18 @@ ], "Hash": "c84fd4f75ea1f5434735e08b7f50fbca" }, + "proxy": { + "Package": "proxy", + "Version": "0.4-27", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "stats", + "utils" + ], + "Hash": "e0ef355c12942cf7a6b91a6cfaea8b3e" + }, "ps": { "Package": "ps", "Version": "1.8.1", @@ -968,6 +1571,61 @@ ], "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4" }, + "readr": { + "Package": "readr", + "Version": "2.1.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "clipr", + "cpp11", + "crayon", + "hms", + "lifecycle", + "methods", + "rlang", + "tibble", + "tzdb", + "utils", + "vroom" + ], + "Hash": "9de96463d2117f6ac49980577939dfb3" + }, + "readxl": { + "Package": "readxl", + "Version": "1.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cellranger", + "cpp11", + "progress", + "tibble", + "utils" + ], + "Hash": "8cf9c239b96df1bbb133b74aef77ad0a" + }, + "rematch": { + "Package": "rematch", + "Version": "2.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "cbff1b666c6fa6d21202f07e2318d4f1" + }, + "rematch2": { + "Package": "rematch2", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tibble" + ], + "Hash": "76c9e04c712a05848ae7a23d2f170a40" + }, "remotes": { "Package": "remotes", "Version": "2.5.0", @@ -992,6 +1650,28 @@ ], "Hash": "47623f66b4e80b3b0587bc5d7b309888" }, + "reprex": { + "Package": "reprex", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "callr", + "cli", + "clipr", + "fs", + "glue", + "knitr", + "lifecycle", + "rlang", + "rmarkdown", + "rstudioapi", + "utils", + "withr" + ], + "Hash": "97b1d5361a24d9fb588db7afe3e5bcbf" + }, "rlang": { "Package": "rlang", "Version": "1.1.5", @@ -1081,6 +1761,37 @@ ], "Hash": "a9881dfed103e83f9de151dc17002cd1" }, + "rvest": { + "Package": "rvest", + "Version": "1.0.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "httr", + "lifecycle", + "magrittr", + "rlang", + "selectr", + "tibble", + "xml2" + ], + "Hash": "0bcf0c6f274e90ea314b812a6d19a519" + }, + "s2": { + "Package": "s2", + "Version": "1.1.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "Rcpp", + "wk" + ], + "Hash": "3c8013cdd7f1d20de5762e3f97e5e274" + }, "sass": { "Package": "sass", "Version": "0.4.9", @@ -1095,6 +1806,39 @@ ], "Hash": "d53dbfddf695303ea4ad66f86e99b95d" }, + "scales": { + "Package": "scales", + "Version": "1.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "RColorBrewer", + "cli", + "farver", + "glue", + "labeling", + "lifecycle", + "munsell", + "rlang", + "viridisLite" + ], + "Hash": "c19df082ba346b0ffa6f833e92de34d1" + }, + "selectr": { + "Package": "selectr", + "Version": "0.4-2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "methods", + "stringr" + ], + "Hash": "3838071b66e0c566d55cc26bd6e27bf4" + }, "sessioninfo": { "Package": "sessioninfo", "Version": "1.2.2", @@ -1108,6 +1852,29 @@ ], "Hash": "3f9796a8d0a0e8c6eb49a4b029359d1f" }, + "sf": { + "Package": "sf", + "Version": "1.0-19", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "DBI", + "R", + "Rcpp", + "classInt", + "grDevices", + "graphics", + "grid", + "magrittr", + "methods", + "s2", + "stats", + "tools", + "units", + "utils" + ], + "Hash": "fe02eec2f6b3ba0e24afe83d5ccfb528" + }, "shiny": { "Package": "shiny", "Version": "1.10.0", @@ -1279,6 +2046,51 @@ ], "Hash": "a84e2cc86d07289b3b6f5069df7a004c" }, + "tidyRSS": { + "Package": "tidyRSS", + "Version": "2.0.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "anytime", + "dplyr", + "glue", + "httr", + "jsonlite", + "magrittr", + "purrr", + "rlang", + "tibble", + "tidyselect", + "vctrs", + "xml2" + ], + "Hash": "bfd32a976e5ac80838ece3256cd7f810" + }, + "tidyr": { + "Package": "tidyr", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "cpp11", + "dplyr", + "glue", + "lifecycle", + "magrittr", + "purrr", + "rlang", + "stringr", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "915fb7ce036c22a6a33b5a8adb712eb1" + }, "tidyselect": { "Package": "tidyselect", "Version": "1.2.1", @@ -1318,6 +2130,46 @@ ], "Hash": "612125521ebc22fd028182761211b5d9" }, + "tidyverse": { + "Package": "tidyverse", + "Version": "2.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "broom", + "cli", + "conflicted", + "dbplyr", + "dplyr", + "dtplyr", + "forcats", + "ggplot2", + "googledrive", + "googlesheets4", + "haven", + "hms", + "httr", + "jsonlite", + "lubridate", + "magrittr", + "modelr", + "pillar", + "purrr", + "ragg", + "readr", + "readxl", + "reprex", + "rlang", + "rstudioapi", + "rvest", + "stringr", + "tibble", + "tidyr", + "xml2" + ], + "Hash": "c328568cd14ea89a83bd4ca7f54ae07e" + }, "timechange": { "Package": "timechange", "Version": "0.3.0", @@ -1352,6 +2204,28 @@ ], "Hash": "76d35ebfaaf291e08c15696c9f2ec96d" }, + "tzdb": { + "Package": "tzdb", + "Version": "0.4.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cpp11" + ], + "Hash": "f561504ec2897f4d46f0c7657e488ae1" + }, + "units": { + "Package": "units", + "Version": "0.8-5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "Rcpp" + ], + "Hash": "119d19da480e873f72241ff6962ffd83" + }, "urlchecker": { "Package": "urlchecker", "Version": "1.0.1", @@ -1408,6 +2282,16 @@ ], "Hash": "62b65c52671e6665f803ff02954446e9" }, + "uuid": { + "Package": "uuid", + "Version": "1.2-1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "34e965e62a41fcafb1ca60e9b142085b" + }, "vctrs": { "Package": "vctrs", "Version": "0.6.5", @@ -1422,6 +2306,42 @@ ], "Hash": "c03fa420630029418f7e6da3667aac4a" }, + "viridisLite": { + "Package": "viridisLite", + "Version": "0.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "c826c7c4241b6fc89ff55aaea3fa7491" + }, + "vroom": { + "Package": "vroom", + "Version": "1.6.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bit64", + "cli", + "cpp11", + "crayon", + "glue", + "hms", + "lifecycle", + "methods", + "progress", + "rlang", + "stats", + "tibble", + "tidyselect", + "tzdb", + "vctrs", + "withr" + ], + "Hash": "390f9315bc0025be03012054103d227c" + }, "waldo": { "Package": "waldo", "Version": "0.6.1", @@ -1456,6 +2376,16 @@ ], "Hash": "cc2d62c76458d425210d1eb1478b30b4" }, + "wk": { + "Package": "wk", + "Version": "0.9.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "37be35d733130f1de1ef51672cf7cdc0" + }, "xfun": { "Package": "xfun", "Version": "0.50", From 169e7c2d9628da4be834c6c591d39975acc13b69 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Thu, 13 Feb 2025 14:26:35 +0100 Subject: [PATCH 05/28] Add area things as vectors instead of datasets --- R/utils.R | 237 ++++++++++++++++++++++++++++++++++++++- data-raw/dkstat_groups.R | 4 +- data/kom_omraade.rda | Bin 1108 -> 0 bytes data/komgrp.rda | Bin 1544 -> 0 bytes 4 files changed, 235 insertions(+), 6 deletions(-) delete mode 100644 data/kom_omraade.rda delete mode 100644 data/komgrp.rda diff --git a/R/utils.R b/R/utils.R index 8b33a4b..3dfe06e 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,7 +1,4 @@ -geographic_vectors <- list( - "komgrp" = dkstat::komgrp, - "kom_omraade" = dkstat::kom_omraade -) + geo_vars <- c( @@ -705,3 +702,235 @@ geo_vars <- c( # # "TILKOMMUNE", # "FRAKOMMUNE", + + +# Create the nested list structure +komgrp <- list( + "1 Hovedstadskommuner" = list( + "101 København" = "København", + "147 Frederiksberg" = "Frederiksberg", + "151 Ballerup" = "Ballerup", + "153 Brøndby" = "Brøndby", + "155 Dragør" = "Dragør", + "157 Gentofte" = "Gentofte", + "159 Gladsaxe" = "Gladsaxe", + "161 Glostrup" = "Glostrup", + "163 Herlev" = "Herlev", + "165 Albertslund" = "Albertslund", + "167 Hvidovre" = "Hvidovre", + "169 Høje-Taastrup" = "Høje-Taastrup", + "173 Lyngby-Taarbæk" = "Lyngby-Taarbæk", + "175 Rødovre" = "Rødovre", + "183 Ishøj" = "Ishøj", + "185 Tårnby" = "Tårnby", + "187 Vallensbæk" = "Vallensbæk", + "190 Furesø" = "Furesø", + "201 Allerød" = "Allerød", + "223 Hørsholm" = "Hørsholm", + "230 Rudersdal" = "Rudersdal", + "240 Egedal" = "Egedal", + "253 Greve" = "Greve", + "269 Solrød" = "Solrød" + ), + + "2 Storbykommuner" = list( + "461 Odense" = "Odense", + "751 Aarhus" = "Aarhus", + "851 Aalborg" = "Aalborg" + ), + + "3 Provinsbykommuner" = list( + "217 Helsingør" = "Helsingør", + "219 Hillerød" = "Hillerød", + "259 Køge" = "Køge", + "265 Roskilde" = "Roskilde", + "330 Slagelse" = "Slagelse", + "370 Næstved" = "Næstved", + "561 Esbjerg" = "Esbjerg", + "607 Fredericia" = "Fredericia", + "615 Horsens" = "Horsens", + "621 Kolding" = "Kolding", + "630 Vejle" = "Vejle", + "657 Herning" = "Herning", + "661 Holstebro" = "Holstebro", + "730 Randers" = "Randers", + "740 Silkeborg" = "Silkeborg", + "791 Viborg" = "Viborg" + ), + + "4 Oplandskommuner" = list( + "210 Fredensborg" = "Fredensborg", + "250 Frederikssund" = "Frederikssund", + "260 Halsnæs" = "Halsnæs", + "270 Gribskov" = "Gribskov", + "316 Holbæk" = "Holbæk", + "320 Faxe" = "Faxe", + "329 Ringsted" = "Ringsted", + "336 Stevns" = "Stevns", + "340 Sorø" = "Sorø", + "350 Lejre" = "Lejre", + "410 Middelfart" = "Middelfart", + "420 Assens" = "Assens", + "430 Faaborg-Midtfyn" = "Faaborg-Midtfyn", + "440 Kerteminde" = "Kerteminde", + "450 Nyborg" = "Nyborg", + "480 Nordfyns" = "Nordfyns", + "575 Vejen" = "Vejen", + "706 Syddjurs" = "Syddjurs", + "710 Favrskov" = "Favrskov", + "727 Odder" = "Odder", + "746 Skanderborg" = "Skanderborg", + "756 Ikast-Brande" = "Ikast-Brande", + "766 Hedensted" = "Hedensted", + "840 Rebild" = "Rebild" + ), + + "5 Landkommuner" = list( + "306 Odsherred" = "Odsherred", + "326 Kalundborg" = "Kalundborg", + "360 Lolland" = "Lolland", + "376 Guldborgsund" = "Guldborgsund", + "390 Vordingborg" = "Vordingborg", + "400 Bornholm" = "Bornholm", + "479 Svendborg" = "Svendborg", + "482 Langeland" = "Langeland", + "492 Ærø" = "Ærø", + "510 Haderslev" = "Haderslev", + "530 Billund" = "Billund", + "540 Sønderborg" = "Sønderborg", + "550 Tønder" = "Tønder", + "563 Fanø" = "Fanø", + "573 Varde" = "Varde", + "580 Aabenraa" = "Aabenraa", + "665 Lemvig" = "Lemvig", + "671 Struer" = "Struer", + "707 Norddjurs" = "Norddjurs", + "741 Samsø" = "Samsø", + "760 Ringkøbing-Skjern" = "Ringkøbing-Skjern", + "773 Morsø" = "Morsø", + "779 Skive" = "Skive", + "787 Thisted" = "Thisted", + "810 Brønderslev" = "Brønderslev", + "813 Frederikshavn" = "Frederikshavn", + "820 Vesthimmerlands" = "Vesthimmerlands", + "825 Læsø" = "Læsø", + "846 Mariagerfjord" = "Mariagerfjord", + "849 Jammerbugt" = "Jammerbugt", + "860 Hjørring" = "Hjørring" + ) +) + + +kom_omraade <- c( + "000 Hele landet", + "1 Hovedstadskommuner", + "2 Storbykommuner", + "3 Provinsbykommuner", + "4 Oplandskommuner", + "5 Landkommuner", + "101 København", + "147 Frederiksberg", + "155 Dragør", + "185 Tårnby", + "165 Albertslund", + "151 Ballerup", + "153 Brøndby", + "157 Gentofte", + "159 Gladsaxe", + "161 Glostrup", + "163 Herlev", + "167 Hvidovre", + "169 Høje-Taastrup", + "183 Ishøj", + "173 Lyngby-Taarbæk", + "175 Rødovre", + "187 Vallensbæk", + "201 Allerød", + "240 Egedal", + "210 Fredensborg", + "250 Frederikssund", + "190 Furesø", + "270 Gribskov", + "260 Halsnæs", + "217 Helsingør", + "219 Hillerød", + "223 Hørsholm", + "230 Rudersdal", + "400 Bornholm", + "411 Christiansø", + "253 Greve", + "259 Køge", + "350 Lejre", + "265 Roskilde", + "269 Solrød", + "320 Faxe", + "376 Guldborgsund", + "316 Holbæk", + "326 Kalundborg", + "360 Lolland", + "370 Næstved", + "306 Odsherred", + "329 Ringsted", + "330 Slagelse", + "340 Sorø", + "336 Stevns", + "390 Vordingborg", + "420 Assens", + "430 Faaborg-Midtfyn", + "440 Kerteminde", + "482 Langeland", + "410 Middelfart", + "480 Nordfyns", + "450 Nyborg", + "461 Odense", + "479 Svendborg", + "492 Ærø", + "530 Billund", + "561 Esbjerg", + "563 Fanø", + "607 Fredericia", + "510 Haderslev", + "621 Kolding", + "540 Sønderborg", + "550 Tønder", + "573 Varde", + "575 Vejen", + "630 Vejle", + "580 Aabenraa", + "710 Favrskov", + "766 Hedensted", + "615 Horsens", + "707 Norddjurs", + "727 Odder", + "730 Randers", + "741 Samsø", + "740 Silkeborg", + "746 Skanderborg", + "706 Syddjurs", + "751 Aarhus", + "657 Herning", + "661 Holstebro", + "756 Ikast-Brande", + "665 Lemvig", + "760 Ringkøbing-Skjern", + "779 Skive", + "671 Struer", + "791 Viborg", + "810 Brønderslev", + "813 Frederikshavn", + "860 Hjørring", + "849 Jammerbugt", + "825 Læsø", + "846 Mariagerfjord", + "773 Morsø", + "840 Rebild", + "787 Thisted", + "820 Vesthimmerlands", + "851 Aalborg" +) + + +geographic_vectors <- list( + "komgrp" = komgrp, + "kom_omraade" = kom_omraade +) diff --git a/data-raw/dkstat_groups.R b/data-raw/dkstat_groups.R index 04f53dd..f0b851d 100644 --- a/data-raw/dkstat_groups.R +++ b/data-raw/dkstat_groups.R @@ -49,7 +49,7 @@ komgrp <- readr::read_csv2("data-raw/komgrp.csv") |> ) |> tibble::deframe() -usethis::use_data(komgrp, compress = "xz", overwrite = TRUE) +usethis::use_data(komgrp, compress = "xz", overwrite = TRUE, internal = TRUE) # Municipality groups with "Hele landet" as well @@ -161,4 +161,4 @@ kom_omraade <- c( "851 Aalborg" ) -usethis::use_data(kom_omraade, compress = "xz", overwrite = TRUE) +usethis::use_data(kom_omraade, compress = "xz", overwrite = TRUE, internal = TRUE) diff --git a/data/kom_omraade.rda b/data/kom_omraade.rda deleted file mode 100644 index aa9411dabba7a8931fe1b5221fc4abf752575a78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1108 zcmV-a1grb~H+ooF0004LBHlIv03iV!0000G&sfah2(|vQ&2UKVgRpfkl( ztnn6!$!Kl^VMGIvukwO8Frd72I!zzinxljuO|VtFVs~Vl#CNd+BD#mC*xm2eC{$*I?Skz@ej3JG zf?6TGy^GKIPygT49ZDgx zPlv$#IoL!^5pPDljcuL6nwdF`7^2M@85na_#W-9O4jMXFWf!|6c}J<6=!A8e)Nu|N zyM~xCuzMe-s-4xQ=K0cyz7fCk){v`|HSQjk{q~t%=*U*%i7c^am>LY*Y6I-$^id&R zMVk>VwOQg6;Mg^L_`d#L6%I#2M0NJ{8nH3F0SbY81@l#)V!fJ(l$6lYEpZ7yha$PP zYHl0AlL*U_fJqRj!-&Sh74FL>TeuFdAVXH`zpRm)Md1_h<81?#>EgUC9v6LjAy*^z z2)7LE?gNKabbXGghhH!SQPvt(L*Yxw`G@|rFnd+8wPlm+bKdUK+lb2nI0+7%aKsi_ zP6jR0^2tJI$+L-z+G7t{k4=Bud)kZ|f8`uAGgy0K8gW)^p?*5rzp1gH@0l?GadIcVD38loex2IhXF=&po}4l7z#nXAEhp?t0^gl^s-@q>+{SZ_Y+$rYLElQTEKh#R#bj@sp(aC5cEPV_DbtA>*p@aI><)11 z@fzkNB<+2cMD&O{%R=Oi7llchQs`H0f_ChL728fu#@y-ZDXcFq6aZTSF6-fecKH>lX0000{9Y}-# a0j&tP5dZ*4BIe6JFb#_W000000a;pOqzbbD diff --git a/data/komgrp.rda b/data/komgrp.rda deleted file mode 100644 index 39cc39a65608bdaaa31b48ede3db27a5cd650f2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1544 zcmV+j2KV{>H+ooF0004LBHlIv03iV!0000G&sfah5`G2CT>vQ&2UKVgRpfkl( ztnn6!$!Kl^VMGIvukwO8Frd72I!zzJS;X}}{eW)pRyUeNE%yrIZKbq>w{Pkc33nhS zZZMtdTK1f#t^VIugU6dWfBY-eL*+T=MDJLU>;`1!1dC%DzRz?Y1lGvk@7Qe}W0*9% zrz(K0cX^&73GVt|??*n6x83o=AI6`9%y+Y2F!Rd0NbQP*=lH%5iy0A4x z{GWoL!ItGEhdM$}U`D&r-D^PX@C`4*JrbcSgy6uDcB`xpgO)j~I)Oy2a!W6U&2)cA^gTD|h(Y>wbs@4E?g}bqpKj`6V(7A$x+l%>RZq7ghkAxYP)t78OotR0 zKOX%!@DYYUu?rMPzj=G*-}3;kc#H>lF;c&afZ;_i^mc}u6vs|46Tl;u<4+JV9UCSP zg1>4BFqk4txBR77-eyPSUx7^gDE4qMLnE-xn-g;iY^JnT1A>WsA+PWrUBkYxdF^*$ zACCw6H}5Xl)zu#Q{`}!aKZ79WiHSG0LSYhx-$0VRz*2cYp4u25C)o*vap~->M;^T~ zpV$c6*^mFHe@qHQc;Xi2#ZuSXWBfbyk<9 z7`sT#sAUf8#sg{yL|kVdU%9?%(J8lMPfOw4CBy6>VM8DnE2qWriGz%*4SiHKB;w}C zpH|56U}l+QD5jWuZ3-o&mLS0+v}5Uyl?R(t=ikVb16A@GIZ`6w%^Tb`9C4#)0(F-! zVNf#L>qx;EF0!YCV^^v>mzBD=uXKfZJ+P^vWs*|p!jPjt!nQoHBmheo6>H`FWL{1q!|Z7|Mk4%4Vcp<<(=|PB@8Nx`MF~ zEQtf6BFn1CG9Y9Y@bo_+fV_R#2TE8FB2_^}=fjR}B;Xed96aYA>{^Dh)I5AJbyabg zVOECRbT%im^~P6h4VJ+h9}+rtcPqzai6uqfcApywC&OO&N)y*ugSg8!Z~%IIL-O00cq#!jk(e*+TTDImx)wsNMdCPY9VaVK(*< z->k;zdfo-xSSD27lwcT;^;yPih*d957m$tv-O^w4Rk_?4dBuct4wpnA$pMQeHEHwn z0&=3t)hRiW)iz*)81xi1Z@^~00k!PRKQ`k=w11Ed+raIEn*Q&=7A9Gpf&7TFih|13 zl^!K4_(U7PiRkOtYuU12P`z>4sGGo!(xzD(4Ox{c>mdKpMW;({6FIQ|Lm50Dm3+G}fr+X%0f=78iv!x;(CcGmY&+2SE4ugs)*$x5+V< z@sNtyBK}=bolHknLaOPcm$|KD0&iJBVFf+;)&i*WgiTnIO>L+-lq#RND*`)Nxewr~ z(2AuxTuY?0w+@#K?4IDlfPTEJpm3ZRD_eDtBLnU<^(aL_?gw4Rg#Gi=!f31YFWUf^ zE!MwDH0M9GZcd)ztg^V!aeG@qt=5)UcI&KlumqgEk4l(!5vCnuv;jWG9%K!t@|9#H zRb;qo+9ZAwJ`}ddz;1}=-V*IA2)^-v_ZO5{dMqN2Kv$?aKFSgdTfl&Ms;a%YWa1ff zzD6kevvb+xQnF*V&w4zW?oZLcUJU4sFr4}A7E1D>7t*US(sj>TVCRd?S=K|iimG`q zIINa3+YeyIaIV6adzD|7Og$tj1t*n-#BNp48MeVIay_|FdY$5kLN;#9DJNZ;QdO0n uIsygj-SC+Ok64SP0001E3ZOIq0pkn*Bme*{WE90dFb#_W000000a;pn@ai4_ From cd6823d3bcaea2dd4e70e4e6519faba367799672 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Thu, 13 Feb 2025 16:35:52 +0100 Subject: [PATCH 06/28] Specify some things --- vignettes/tech-specs-for-geodk.Rmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vignettes/tech-specs-for-geodk.Rmd b/vignettes/tech-specs-for-geodk.Rmd index ce6b343..beb5039 100644 --- a/vignettes/tech-specs-for-geodk.Rmd +++ b/vignettes/tech-specs-for-geodk.Rmd @@ -48,8 +48,8 @@ dkstat::dst_get_all_data("laby04") |> When accessing data from a table, e.g. "laby04" there is no obvious way to know what column is geographic. ```{r} -dkstat::dst_get_all_data("laby04") |> - distinct(OMRÅDE, .keep_all = TRUE) |> +dkstat::dst_get_all_data("laby01") |> + distinct(KOMGRP, .keep_all = TRUE) |> tail() ``` @@ -65,7 +65,7 @@ Below you can find the description of each S3-class that is used (/abused) to en ## Classes -Each type of geographic variable has its own S3 class. The class is determined by what observations is included in the variable. The class-assignment is done by a series of custom class-constructors called `new_dkstat_*()`. One example is `new_dkstat_KOMGRP()` which assigns the S3 class `dkstat_KOMGRP` to a dataset. The class is assigned "after the fact", as Wickham calls it, ensuring that the usual behaviour of a data.frame is preserved for all the functions that don't know about these special classes (e.g. the `{dplyr}` functions). +Each type of geographic variable has its own S3 class. The class is determined by what observations is included in the variable. The class-assignment is done by a series of custom class-constructors called `new_dkstat_*()`. One example is `new_dkstat_KOMGRP()` which assigns the S3 class `dkstat_KOMGRP` to a dataset. The class is assigned "after the fact", as Wickham calls it, ensuring that the usual behaviour of a data.frame is preserved, through inheritance for all the functions that don't know about these special classes (e.g. the `{dplyr}` functions). Thus, the dkstat-classes are subclasses of `data.frame`. ## Method dispatch From 2ffe94f03d503a1c286ec0f62e94ec869c92fcad Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:30:19 +0100 Subject: [PATCH 07/28] Add updated spec for geodk integration --- vignettes/tech-specs-for-geodk.Rmd | 62 +++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/vignettes/tech-specs-for-geodk.Rmd b/vignettes/tech-specs-for-geodk.Rmd index beb5039..88369c1 100644 --- a/vignettes/tech-specs-for-geodk.Rmd +++ b/vignettes/tech-specs-for-geodk.Rmd @@ -65,26 +65,78 @@ Below you can find the description of each S3-class that is used (/abused) to en ## Classes -Each type of geographic variable has its own S3 class. The class is determined by what observations is included in the variable. The class-assignment is done by a series of custom class-constructors called `new_dkstat_*()`. One example is `new_dkstat_KOMGRP()` which assigns the S3 class `dkstat_KOMGRP` to a dataset. The class is assigned "after the fact", as Wickham calls it, ensuring that the usual behaviour of a data.frame is preserved, through inheritance for all the functions that don't know about these special classes (e.g. the `{dplyr}` functions). Thus, the dkstat-classes are subclasses of `data.frame`. +Each type of geographic variable has its own S3 class. The class is determined by what observations is included in the variable. The class-assignment is done by a series of custom class-constructors called `new_dkstat_*()`. One example is `new_dkstat_Denmark_municipality_07()` which assigns the S3 class `dkstat_Denmark_municipality_07` to a dataset. The class is assigned "after the fact", as Wickham calls it, ensuring that the usual behaviour of a data.frame is preserved, through inheritance for all the functions that don't know about these special classes (e.g. the `{dplyr}` functions). Thus, the dkstat-classes are subclasses of `data.frame`. The class names are derived from the API and maps 1:1 to the `map` value that is returned for geographic variables. ## Method dispatch -The S3 generic can be found in `geodk::geodk_enrich()`. The individual methods also live in `{geodk}`. This is to not take on `{geodk}` as a dependency in `{dkstat}`. The S3 method for the municipality group (KOMGRP) from above is called `geodk_enrich.dkstat_KOMGRP()`. Please [open an issue](https://github.com/rOpenGov/geodk/issues) if you would like to help add a method from another data source. +The S3 generic can be found in `geodk::geodk_enrich()`. The individual methods also live in `{geodk}`. This is to not take on `{geodk}` as a dependency in `{dkstat}`. The S3 method for the municipality group (Denmark_municipality_07) from above is called `geodk_enrich.dkstat_Denmark_municipality_07()`. Please [open an issue](https://github.com/rOpenGov/geodk/issues) if you would like to help add a method from another data source. # Custom classes -## Municipality groups +The API provides 14 different map-levels from which I have based the classes. This makes it very easy to add the right one. In `{dkstat}` `data-raw/dst_map.R` you can find a script that checks all tables for *map* variables and adds each new one to a list. This gives the below vector. + +```{r} +#> [1] "Denmark_municipality_07" "Verden_dk2" +#> [3] "denmark_cities_19" "denmark_parish_23_4c" +#> [5] "denmark_municipalitygroups_24" "Denmark_region_07" +#> [7] "Denmark_rural_07" "denmark_multimember_constituency_23" +#> [9] "denmark_deanary_23" "europe_dk" +#> [11] "Verden_dk" "Europa_DK3" +#> [13] "Denmark_county" "Verden_dk4" +``` + +Some of the geographic levels, such as "Verden_dk" includes other countries. This data is not available from `{geodk}` thus leading to a message for the user informing them of this and then asking if it should add geometry for Denmark. + +## Denmark_municipality_07 - Municipalities and groups The municipality grouping that are specified by Statistics Denmark are described [on this website](https://www.dst.dk/da/Statistik/dokumentation/nomenklaturer/kommunegrupper). This grouping includes both the individual municipality and five groupings. Take a look at the link if you would like to learn more. In the `{geodk}` backend I have created a list containing all the municipality names with both Statistics Denmark-naming and geodk-naming. In addition to that, the list is ordered by the municipality grouping. -This grouping is assigned the `dkstat_KOMGRP` class in addition to the `data.frame` class it already has. +This grouping is assigned the `dkstat_Denmark_municipality_07` class in addition to the `data.frame` class it already has. -The method for `dkstat_KOMGRP` first filters the groupings from the individual municipalities. A list of the individual municipalities and groupings, along with their specific ids is stored in `{geodk}`. It is not exported to the user. +The method for `dkstat_Denmark_municipality_07` first filters the groupings from the individual municipalities. A list of the individual municipalities and groupings, along with their specific ids is stored in `{geodk}`. It is not exported to the user. After filtering, it assigns the individual municipality geometries. The grouping geometries are also assigned as well as a column indicating the geographic nature of the observation - Is it a overall grouping or an individual municipality? The municipalities that make up the groupings are split per group and run through `sf::st_union()` to be returned as a `sf` geometry per group. +## Verden_dk2 + + +## denmark_cities_19 + + +## denmark_parish_23_4c + + +## denmark_municipalitygroups_24 + + +## Denmark_region_07 + + +## Denmark_rural_07 + + +## denmark_multimember_constituency_23 + + +## denmark_deanary_23 + + +## europe_dk + + +## Verden_dk + + +## Europa_DK3 + + +## Denmark_county + + +## Verden_dk4 + # References From 749dd5b08a2ed5e3d419d636b1c9a062c075d85e Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:31:07 +0100 Subject: [PATCH 08/28] Implement all constructors for the 14 map levels provided by the api At some point it would be nice to have more specificity over what labels are included in which levels, but this will have to do for now --- R/determine_geographic_properties.R | 44 +++++++-------- R/dst_get_all_data.R | 8 +-- R/dst_get_data.R | 4 +- R/dst_meta.R | 10 +++- R/dst_meta_map.R | 36 ++++++++++++ R/s3_constructors.R | 84 ++++++++++++++++++++++++++++ data-raw/dst_map.R | 63 +++++++++++++++++++++ data/tables.rda | Bin 47279 -> 46031 bytes man/dst_get_all_data.Rd | 3 +- man/dst_meta.Rd | 5 +- 10 files changed, 225 insertions(+), 32 deletions(-) create mode 100644 R/dst_meta_map.R create mode 100644 data-raw/dst_map.R diff --git a/R/determine_geographic_properties.R b/R/determine_geographic_properties.R index 7dbf075..b453898 100644 --- a/R/determine_geographic_properties.R +++ b/R/determine_geographic_properties.R @@ -1,41 +1,39 @@ # determine_geographic_properties.R # This file contains the logic to decide what kind of geographic information is # included in a given dataset. The function is mainly used in -# `dst_get_all_data()` +# `dst_get_data()` - Thus affecting `dst_get_all_data()` -determine_geographic_properties <- function(df) { +determine_geographic_properties <- function(table, df) { clnms <- colnames(df) - if (is_geographic(clnms)) { - chosen_constructor <- choose_geo_class(df, clnms) + meta <- dst_meta(table, lang = "da", geo = TRUE) + + if (is_geographic(meta)) { + chosen_constructor <- choose_geo_class(meta) chosen_constructor(df) } else { return(df) } } -is_geographic <- function(varnames) { - # If any of the variable names are recorded as geographic, return TRUE - any(varnames %in% geo_vars) +# Check if the metadata indicates a geographic variable +is_geographic <- function(meta) { + if (is.null(meta)) { + return(FALSE) + } else if (!is.null(meta)) { + return(TRUE) + } } -choose_geo_class <- function(df, clnms) { - g_vars <- intersect(geo_vars, clnms) +# Choose a class constructor +choose_geo_class <- function(meta) { - if (g_vars == "OMRÅDE") { - if (identical(unique(df$OMRÅDE), geographic_vectors[["kom_omraade"]])) { - new_dkstat_kom_omraade - } else if (identical(unique(df$OMRÅDE), geographic_vectors[["komgrp"]])) { - new_dkstat_KOMGRP - } - } + # Get the map variable + meta_class <- meta$variables$map - if (g_vars == "KOMGRP") { - if (identical(unique(df$KOMGRP), geographic_vectors[["kom_omraade"]])) { - new_dkstat_kom_omraade - } else if (identical(unique(df$KOMGRP), geographic_vectors[["komgrp"]])) { - new_dkstat_KOMGRP - } - } + # Paste class constructor name prefix with class name and get function + func <- paste0("new_dkstat_", meta_class) |> get() + + return(func) } diff --git a/R/dst_get_all_data.R b/R/dst_get_all_data.R index 70479e0..012a3f4 100644 --- a/R/dst_get_all_data.R +++ b/R/dst_get_all_data.R @@ -6,7 +6,8 @@ #' not need to specify anything other than a table name and you will be given #' the entire contents of the table in a nice long format. This is useful for #' you, if you would like to filter the table with e.g. `{dplyr}` functions or -#' save the entire table for archival. +#' save the entire table for archival. If the table is larger than the max +#' 1.000.000 cells, then you will have to use `dst_get_data()`. #' #' @export #' @inheritParams dst_get_data @@ -23,15 +24,14 @@ dst_get_all_data <- function(table, lang = "da", parse_dst_tid = TRUE) { query <- get_var_options(metadata, variable_names) # Request table with query params - response <- dst_get_data( + data <- dst_get_data( table = table, query = query, lang = lang, + # format = "BULK", parse_dst_tid = parse_dst_tid ) - data <- determine_geographic_properties(response) - return(data) } diff --git a/R/dst_get_data.R b/R/dst_get_data.R index d6049e7..706d40b 100644 --- a/R/dst_get_data.R +++ b/R/dst_get_data.R @@ -133,5 +133,7 @@ dst_get_data <- function(table, dst_data$TID <- dst_date_parse(dst_date = dst_data$TID) } - return(dst_data) + data <- determine_geographic_properties(table, dst_data) + + return(data) } diff --git a/R/dst_meta.R b/R/dst_meta.R index 6a8a192..e72a72a 100644 --- a/R/dst_meta.R +++ b/R/dst_meta.R @@ -8,8 +8,10 @@ #' @param table The name of the table you want meta data for. #' @param ... Ignored. #' @param lang You can choose "en" for english or "da" for danish. +#' @param geo You can choose if the function should return the geographic +#' properties for the metadata. Mostly for internal use. #' @export -dst_meta <- function(table, ..., lang = "da") { +dst_meta <- function(table, ..., lang = "da", geo = FALSE) { ## Create and parse url dkstat_url <- paste0("http://api.statbank.dk/v1/tableinfo/", table, "?") dkstat_url <- httr::parse_url(url = dkstat_url) @@ -27,7 +29,11 @@ dst_meta <- function(table, ..., lang = "da") { ) ## Structure results - meta <- dst_meta_parse(meta, lang) + if (isFALSE(geo)) { + meta <- dst_meta_parse(meta, lang) + } else if (isTRUE(geo)) { + meta <- dst_meta_map(meta, lang) + } return(meta) } diff --git a/R/dst_meta_map.R b/R/dst_meta_map.R new file mode 100644 index 0000000..df517d1 --- /dev/null +++ b/R/dst_meta_map.R @@ -0,0 +1,36 @@ +#' This function parses the JSON from the StatBank. +#' (http://www.statistikbanken.dk/statbank5a/ or http://www.dst.dk) and +#' retrieves the mapping information for all appropriate variables +#' +#' @description The function has been adapted from `dst_meta` to only retrieve +#' the geographic labels. +#' +#' +#' @inheritParams dst_meta_parse +#' @noRd +dst_meta_map <- function(meta, lang) { + # Get basic info on the table. + # The basics contains the table name/id and the short text of what is in the + # table + basics_names <- c("id", "text") + basics <- meta[names(meta) %in% basics_names] + + # Get the description of the variables. + # If map does not exist, we return a NULL + if (!"map" %in% colnames(meta[["variables"]])) {return(NULL)} + variables <- meta[["variables"]][, c("id", "text", "map")] |> + na.omit() + + # Structure the values the user can choose in their query + # values <- meta[["variables"]][, "values"] + # names(values) <- variables$id + + # Retrieve the geographic levels + # values <- values[names(values) %in% variables$id] + + # Return the data as a list. + return(list( + "basics" = basics, + "variables" = variables + )) +} diff --git a/R/s3_constructors.R b/R/s3_constructors.R index dcf4b8d..534d01f 100644 --- a/R/s3_constructors.R +++ b/R/s3_constructors.R @@ -16,3 +16,87 @@ new_dkstat_kom_omraade <- function(x) { class(x) <- c("dkstat_kom_omraade", class(x)) return(x) } + +new_dkstat_Denmark_municipality_07 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Denmark_municipality_07", class(x)) + return(x) +} + +new_dkstat_Verden_dk2 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Verden_dk2", class(x)) + return(x) +} + +new_dkstat_denmark_cities_19 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_denmark_cities_19", class(x)) + return(x) +} + +new_dkstat_denmark_parish_23_4c <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_denmark_parish_23_4c", class(x)) + return(x) +} + +new_dkstat_denmark_municipalitygroups_24 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_denmark_municipalitygroups_24", class(x)) + return(x) +} + +new_dkstat_Denmark_region_07 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Denmark_region_07", class(x)) + return(x) +} + +new_dkstat_Denmark_rural_07 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Denmark_rural_07", class(x)) + return(x) +} + +new_dkstat_denmark_multimember_constituency_23 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_denmark_multimember_constituency_23", class(x)) + return(x) +} + +new_dkstat_denmark_deanary_23 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_denmark_deanary_23", class(x)) + return(x) +} + +new_dkstat_europe_dk <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_europe_dk", class(x)) + return(x) +} + +new_dkstat_Verden_dk <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Verden_dk", class(x)) + return(x) +} + +new_dkstat_Europa_DK3 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Europa_DK3", class(x)) + return(x) +} + +new_dkstat_Denmark_county <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Denmark_county", class(x)) + return(x) +} + +new_dkstat_Verden_dk4 <- function(x) { + stopifnot(is.data.frame(x)) + class(x) <- c("dkstat_Verden_dk4", class(x)) + return(x) +} diff --git a/data-raw/dst_map.R b/data-raw/dst_map.R new file mode 100644 index 0000000..82d119d --- /dev/null +++ b/data-raw/dst_map.R @@ -0,0 +1,63 @@ +# dst_map.R +# This file is created to get all the map-levels provided by the API. They are +# used for the integration with `{geodk}` + +# Load package +devtools::load_all(".") + +# Define custom function to get metadata (this is extracted from dst_meta()) +get_meta <- function(table, lang = "da") { + dkstat_url <- paste0("http://api.statbank.dk/v1/tableinfo/", table, "?") + dkstat_url <- httr::parse_url(url = dkstat_url) + + ## Insert query + dkstat_url$query <- list("lang" = lang, "format" = "JSON") + + ## Get data + meta <- httr::GET(url = dkstat_url) + + ## Parse from JSON + meta <- jsonlite::fromJSON( + txt = httr::content(meta, as = "text"), + simplifyDataFrame = TRUE + ) + + return(meta) +} + +# Get all tables +tbls <- dst_get_tables()$id +# tbls <- c("laby04", "vandud") + +# Define empty map list +maps <- list() + +# Loop for getting map label for each table +for (table in tbls) { + cat("Processing:", table, "\n") + x <- get_meta(table) |> + dst_meta_map() + if (!"map" %in% colnames(x$variables)) { + cat(table, "does not have a geographic label", "\n") + } else { + cat(table, "has", x$variables$map, "\n") + maps[table] <- x$variables$map + print(maps) + } +} + +# Get a unique list of all the levels +map_levels <- maps |> + unname() |> + unlist() |> + unique() + +# Get a flat list +flat <- unlist(maps) + +# Extract the name-value pairs for the first observation of each map-type +map_types <- maps[match(map_levels, flat)] + + +muni <- flat[flat %in% map_levels[1]] |> + names() diff --git a/data/tables.rda b/data/tables.rda index e2f4dc1f5b2a0369d39b0a7908d2b367d7883756..a0af0e7afadbe5f498b0e4d115c5f456882b726d 100644 GIT binary patch literal 46031 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 (Qq=e@O#j{W72iQ;oJcoy{K+70;gLm?(BD}=O3 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 Lzhqp9lL7I6JL-fY diff --git a/man/dst_get_all_data.Rd b/man/dst_get_all_data.Rd index 82e926e..83a8ad6 100644 --- a/man/dst_get_all_data.Rd +++ b/man/dst_get_all_data.Rd @@ -21,7 +21,8 @@ provides all the query parameters on the user's behalf. You, as a user, do not need to specify anything other than a table name and you will be given the entire contents of the table in a nice long format. This is useful for you, if you would like to filter the table with e.g. \code{{dplyr}} functions or -save the entire table for archival. +save the entire table for archival. If the table is larger than the max +1.000.000 cells, then you will have to use \code{dst_get_data()}. } \seealso{ Other Data retrival functions: diff --git a/man/dst_meta.Rd b/man/dst_meta.Rd index ac9cce9..12b8683 100644 --- a/man/dst_meta.Rd +++ b/man/dst_meta.Rd @@ -6,7 +6,7 @@ Statistics Denmark. (http://www.statistikbanken.dk/statbank5a/ or http://www.dst.dk)} \usage{ -dst_meta(table, ..., lang = "da") +dst_meta(table, ..., lang = "da", geo = FALSE) } \arguments{ \item{table}{The name of the table you want meta data for.} @@ -14,6 +14,9 @@ dst_meta(table, ..., lang = "da") \item{...}{Ignored.} \item{lang}{You can choose "en" for english or "da" for danish.} + +\item{geo}{You can choose if the function should return the geographic +properties for the metadata. Mostly for internal use.} } \description{ This function POSTs a request for meta data on a table from Statistics From 73da9f651f6d84e41a2f38295c4ec677d75b38f2 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:43:24 +0100 Subject: [PATCH 09/28] Import na.omit --- NAMESPACE | 1 + R/dst_meta_map.R | 1 + 2 files changed, 2 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index c2f0446..2edacaa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,5 +5,6 @@ export(dst_get_data) export(dst_get_tables) export(dst_meta) export(dst_search) +importFrom(stats,na.omit) importFrom(utils,read.csv) importFrom(utils,read.csv2) diff --git a/R/dst_meta_map.R b/R/dst_meta_map.R index df517d1..8ef1aac 100644 --- a/R/dst_meta_map.R +++ b/R/dst_meta_map.R @@ -7,6 +7,7 @@ #' #' #' @inheritParams dst_meta_parse +#' @importFrom stats na.omit #' @noRd dst_meta_map <- function(meta, lang) { # Get basic info on the table. From 784a751c1a5389d9736e54dd6e4fcf7ff90334d0 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:43:34 +0100 Subject: [PATCH 10/28] Remove unused vector that was commented out anyway --- R/utils.R | 675 ------------------------------------------------------ 1 file changed, 675 deletions(-) diff --git a/R/utils.R b/R/utils.R index 3dfe06e..2a4d691 100644 --- a/R/utils.R +++ b/R/utils.R @@ -29,681 +29,6 @@ geo_vars <- c( "LANDDEL" ) -# c( -# "AKTOER", -# "FINANSKILDE1", -# "FINANSKILDE", -# "MODSEKTOR", -# "LAND", -# "RESTANCE", -# "DELTYP", -# "BRUTNETUDG", -# "FUNK1", -# "DRANST", -# "ART", -# "GRUPPERING", -# "DRANST1", -# "REGI07A", -# "REGI07", -# "TVGRP", -# "NATGRUP", -# "SKATPCT", -# "INDKOMST", -# "SKATGRL", -# "SKATPRO", -# "SKAT", -# "INDSKAT", -# "POST", -# "INDUDBOP", -# "UHBEGREB", -# "INDUD", -# "BALANC", -# "INDSEK", -# "VALUTA", -# "VIRKSTRRDA", -# "EJERSKAB", -# "HOVBRAN", -# "KONC", -# "PLAND", -# "HANDEL", -# "LANDGRP", -# "VARE", -# "DATAKILDE", -# "SITC", -# "INDEKSTYPE", -# "SAESON2", -# "NATION", -# "DATA", -# "UDSEK", -# "INSTRNAT", -# "RETNAT", -# "UDLBRANCHE", -# "INDLBRANCHE", -# "VAREGR", -# "HOVED", -# "VARGR", -# "BAGOPL", -# "HUSSTAND", -# "SAMIND", -# "BOLFORM", -# "EJENDOMSKATE", -# "EJKAT20", -# "OVERDRAG", -# "VURDERING", -# "URBANGRAD", -# "UDGTYP", -# "KURTYP", -# "OPGOER", -# "UDINDLÅN", -# "LØBETID1", -# "RENTFIX1", -# "LAANSTR", -# "RENTFIX", -# "LAANSTRREPO", -# "INSTITYPE", -# "PAPIR", -# "KUPON", -# "LØBETID", -# "UDSTEDSEKTOR", -# "INVSEKTOR", -# "VÆRDIAN", -# "TYPREAL", -# "LØBETID3", -# "LØBETID2", -# "KUPON2", -# "UDSTED", -# "DAEKOBL", -# "DATAT", -# "ISNINAVN", -# "UDSTEDBRANC", -# "HOLBRANC", -# "ISIN", -# "UAKT", -# "OPT", -# "HOVED1", -# "KUPON1", -# "UDSTLAND", -# "INVESTOR", -# "INVEST1", -# "UDSTLAND2", -# "UDLKAT", -# "VAERDI1", -# "INVESTLAND", -# "TRANSAKT1", -# "DIMENSION", -# "KORTYPE", -# "PRIVATERHVERV", -# "KORTTEK", -# "MISBRUG2", -# "ANVSTED", -# "KORTUDSTED", -# "ENHED1", -# "HAEVIND", -# "BETJEN", -# "RET", -# "GEODAEK", -# "KREDIT", -# "INIT", -# "VISITATION", -# "YDTYPDETAL", -# "HERKOMST1", -# "BERET", -# "MORUD", -# "FARUD", -# "DAGPENGERET", -# "EKSISTENS", -# "UDDKOMB", -# "SOCIALSTATUS", -# "UGER", -# "BARNFAM", -# "FORAELDREDAGPENGE", -# "MORUDD", -# "FARUDD", -# "FORAELDREUDD", -# "MODTAG1", -# "PENSIONSTATUS", -# "LTIMER", -# "FORAN", -# "ANBRINGELSE", -# "ADMKOM", -# "ANBRINGAARSAG", -# "INDSATSER", -# "UNDERRETERE", -# "UNDERRET", -# "AFFALDSOPR", -# "AKTI", -# "AKTP", -# "VENTETIDGARANTI", -# "MYNDIGHEDSKOM", -# "AFSLUTSTATUS", -# "BEBOSTAT", -# "HERKAMS", -# "OPHOLD2", -# "OVERNAT", -# "MLGRP", -# "MND", -# "SERVYD", -# "HJEMBESOEG", -# "TIMEUGE", -# "KONAMS", -# "OVERTRÆD", -# "ANMSIGT", -# "AFGØRELSE", -# "STRAFLANG", -# "VARTILBAGE", -# "STRAFART", -# "OVER", -# "OVER1", -# "STRAFART1", -# "OVER2", -# "STRAFART2", -# "RECHEN", -# "TIDLDOM", -# "OVERNAT1", -# "FDOMALD", -# "LOVOV", -# "AVFFS", -# "FRISTRAF", -# "ADOM", -# "AFSLUT", -# "BOPDK", -# "AFSAVN", -# "SPORG", -# "SVAR", -# "KOAL", -# "SVAERHED1", -# "INDKOMGRP", -# "HFUIGANG", -# "HFUDD2", -# "INDIKATOR1", -# "UDDSTAT", -# "FORUDD1", -# "FORIND", -# "FORBESK", -# "GRUNDSKOL", -# "GRUNDBEL", -# "DKMAT", -# "IETYPE", -# "STATUSVID", -# "GRUNDKAR", -# "FSTATUS", -# "OMRÅDE1", -# "KLASSE", -# "SKTPE", -# "ELEV", -# "UDDDL", -# "UDDFORM", -# "HOMR", -# "UDVEKSLING", -# "OPVAR", -# "INSTI", -# "AFGAARG", -# "AFGKLAS", -# "AFGREG", -# "STATUSTID", -# "UDDANGROUP", -# "STATUSAFG", -# "ALDERLEV", -# "STARTUD", -# "STAT", -# "STARTALD", -# "FUDDOMR", -# "TIDSPUNKTER", -# "FORMEL", -# "UFORMEL", -# "UDDGRUND", -# "EFTERVIR", -# "ANSATTE", -# "INSTTYP", -# "KURSUS", -# "HOEJ_UDD_FAM", -# "AEKVI_FAM_INDKOMST", -# "PERS_INDK", -# "BOPLAND", -# "FUI01", -# "FUI08", -# "LEVRTYP", -# "VIDOMR", -# "PERSTYP", -# "FUI14", -# "SEKVID", -# "PERSONKAT", -# "FAGET", -# "DRIFT1", -# "PCTBNP", -# "UDGPOST", -# "VIDENHOVED", -# "SOCFORM", -# "AARVAERK", -# "OIN01", -# "INNO", -# "NYHEDSGRAD", -# "OIN03", -# "OIN02", -# "INNBRANCHE", -# "INNPRO", -# "INNPROCES", -# "INNSAM", -# "RESSOMR", -# "IPR1", -# "IPR2", -# "BRANCHEDB071019127", -# "BRANCHEDB0710TIL127", -# "FIRMSTR", -# "BRANCHEDB0710", -# "VIRKF1", -# "FIRMAALDER", -# "KONCERNSTOR", -# "KONCERN", -# "ARBSTRDK", -# "STØRRELSE", -# "VIRKSTR", -# "BRANCHEDB0721", -# "BESTPOST", -# "VFORM", -# "BESTMEDL", -# "FIRMASTAT", -# "VARIA", -# "STARTAAR", -# "VIRKTYP1", -# "LEVTID", -# "OMSÆTNING", -# "BESK", -# "BRANCHEREV2", -# "EMNER", -# "ANVEND", -# "AKTIVI", -# "REGNSKPOSTER", -# "FINAKT", -# "FINFORM", -# "UDFALD", -# "LAANEFIN", -# "BELØB", -# "OFFGRP", -# "FONDSTYPE", -# "BEVILLING2", -# "VIRKE", -# "MODTAG", -# "MODTAGER", -# "FAGOMR", -# "FONDSMIDLER", -# "UNDEROMRÅDE", -# "LANDE", -# "FIRMA", -# "FUNKTIONER", -# "JOBTYP", -# "DESTINA", -# "MOTIV", -# "BETYD", -# "FORTYP", -# "PRODUKT", -# "INVEST", -# "FUI6", -# "BEDRIFTSTAND", -# "KVARTIL", -# "BEDRIFTAARS", -# "BRUGSTYPE", -# "PRODGREN1", -# "REGNP", -# "REGNH", -# "KAPIT", -# "KORNART", -# "AREALSTOR", -# "BEDRIFT", -# "AREAL1", -# "UDBEDRIFT", -# "BDFALDER", -# "BEDRIFTSTR", -# "FORP", -# "BESKLAND", -# "PRAETEK", -# "UDALDER", -# "AFGRØDE", -# "AREALAFG", -# "OMR2", -# "SORT", -# "TRE", -# "KULT", -# "DYR", -# "BESAET", -# "HUSDYRTYPE", -# "DYRKAT", -# "OPRIND", -# "AK", -# "STRUK", -# "PROD", -# "VÆKST", -# "AREAL2", -# "FODER2", -# "VANDTY", -# "FODER1", -# "FODER", -# "STOFTYPE", -# "MÅLEENHED", -# "PESTICIDGR", -# "PESTICIDTYPE", -# "BEVOKSNING", -# "TRAESORT", -# "FISKFAR", -# "LAENG", -# "TONNAGE", -# "FANGST", -# "LANDING1", -# "FISK", -# "FARLAENGD", -# "ANLAEG", -# "FISKSKAL", -# "RÅSTOFTYPE", -# "VARGR6", -# "VARGR2", -# "OMSTYPE", -# "HOVEDGRP", -# "MARKED1", -# "STANDGRP", -# "BYGFASE", -# "BYGHERRE", -# "AAR", -# "BYGGESAG", -# "ÅR", -# "ARBART", -# "AREALINT", -# "AREALTYPE", -# "OPVARM", -# "TAGMAT", -# "YDREMAT", -# "HINDEKS", -# "DINDEKS", -# "BOLTYP", -# "OVERNATF", -# "NATION1", -# "KAPACITET", -# "SEG", -# "CERT", -# "FREMÅR", -# "FREMMD", -# "KAPMEDIE", -# "FARVAND", -# "TRANSMID", -# "RAPINST", -# "SEKKORNAT", -# "SEKTOR2", -# "RENTEFIX1", -# "FORMAAL1", -# "RENTE", -# "RENTEREF", -# "AFDRAG", -# "RENTETYPE", -# "EJENKATNAT", -# "DISAGGBALPOST", -# "AGGBALPOST", -# "AKTTYP", -# "EGENSEKTOR", -# "BETALFRIST", -# "SPECNAT", -# "INSTITUTTYPE", -# "NYUD", -# "BALPOSTNAT1", -# "INVESTFOND", -# "HOVEDKAT", -# "FORVALT", -# "RISIKO", -# "VARDIPAP", -# "UDSTEDKAT", -# "VIRKTYPNB", -# "INVESTNAT", -# "MARKVAERDI", -# "MEDIER", -# "OMSEKS", -# "BEDØMMELSE", -# "FORLØB", -# "AARSAG", -# "OPG", -# "PAAFOR", -# "BILTYPE", -# "REGBIL", -# "BILSEG", -# "DRIV", -# "BRUG", -# "ENERGI", -# "KM", -# "KOEBMOENS", -# "KOEBTYPE", -# "BOL", -# "RAADMOENS", -# "BESTAND", -# "SOMKOM", -# "EGEN", -# "BESTANDDEL", -# "TVAEGT", -# "AKSLER", -# "SIDDE", -# "TOG", -# "VOGN2", -# "SKIBTYPE", -# "SKIBREG", -# "BT", -# "VEJSTR", -# "VEJTYPE", -# "TRANSPORT", -# "BANE", -# "FLAG", -# "HAVN", -# "LUFTHAVN", -# "FLYVNING", -# "BANEL", -# "ROR", -# "SDGSERVICE", -# "BANES", -# "FÆRGE", -# "PASSAGER", -# "PÅSTIG1", -# "AFSTIG1", -# "DESTI", -# "REJSE", -# "KØRART", -# "TYPEVÆGT", -# "BILALDER", -# "TURKM", -# "VOGN", -# "LÆS", -# "GODS", -# "PÅREGION", -# "AFREGION", -# "LASTTYPE", -# "REG", -# "VOGN1", -# "START1", -# "SLUT1", -# "PÅLAND", -# "AFLAND", -# "LAST", -# "TRANSPORT1", -# "UHELDA", -# "UHELDSIT", -# "BYLAND", -# "HAST", -# "KLOK", -# "UGE", -# "MODPART", -# "TRANSINV", -# "UHELD", -# "SKADE", -# "PERSART", -# "GADEVEJ", -# "IUDENFOR", -# "SPIRIT", -# "INDBLAND", -# "KALDER", -# "ALCO", -# "INDBERET", -# "SKADEDIAG", -# "PKATEGORI", -# "UTYPE", -# "OMFANG", -# "MUSEER", -# "AFDLING", -# "AKTIVITET", -# "BESØGSTYPE", -# "ALDERK", -# "BESØG", -# "GENRE", -# "ADGANG", -# "ZOOKAT", -# "ZOO", -# "BYGTYP", -# "ANKAT", -# "ARKIV", -# "SAMLING", -# "OPGOER1", -# "MATER", -# "MATYPELEK", -# "UDLÅNSSTED", -# "AFSTANDBIB", -# "DIGITTJE", -# "BIB2", -# "KILD", -# "PLACERING", -# "LAESINTERVAL", -# "UDGIVFREK", -# "BOGER", -# "GEOOMR", -# "MEDIE", -# "BOGTYPE", -# "UDGAVE", -# "SPROG", -# "OVERSAT", -# "BTYPE", -# "OPLAG1", -# "FORMAT", -# "HOVEDGENRE", -# "UDGIVELSESSPROG", -# "RELATION", -# "INSP", -# "LAESFREK", -# "SADER", -# "BIOGRAF", -# "BIO", -# "NATION2", -# "BIOSTOR", -# "TYPMAL", -# "URPRIM", -# "FILMKAT", -# "CENSUR", -# "SPILLEUGE", -# "KULTUR", -# "LOKATION", -# "FINANSTYPE", -# "INDTTYPE", -# "TEATTYP", -# "PUBGRUP", -# "SCENE", -# "TEATER", -# "MGK", -# "ARBREG", -# "OEKNOGL", -# "KUNSTART", -# "SOCIALSAM", -# "MUSIKSAM", -# "DISTRIB", -# "RETTIGHED", -# "MUSVÆRK", -# "KONCERTARRANGØR", -# "KONCERTSTØRRELSE", -# "ARRANGEOR", -# "BRANCHEKULT", -# "UDDTYPE", -# "CL_REGION", -# "MESTER", -# "IDRAET", -# "MEDALJE", -# "DICIPLIN", -# "PRÆSTATION", -# "RELATIV", -# "RANG", -# "KØNALDER", -# "DELTAG1", -# "TIDBRUG", -# "ORGAN1", -# "FORBACK", -# "SPORTS", -# "TILSKUER", -# "IDRATAKT", -# "STED", -# "IDRFAC", -# "ORGANISATION", -# "SENANV", -# "SENKOB", -# "UDSTYR", -# "ADFÆRD", -# "OVERV", -# "FORMAAL", -# "FORHAND", -# "BREDBAAND", -# "BREDHAST", -# "ANTALANDEL", -# "PRIVAT", -# "ANNONCERING", -# "FORBRUG", -# "TJEN1", -# "KUNSTOMR", -# "INDGRUND", -# "VINDKOMST", -# "KULTUREMNE", -# "UDDINST", -# "DIMMITEND", -# "LEDTYP", -# "INTNAT", -# "EFFEKTER", -# "KREATIVEERHVERV", -# "FINANSART", -# "STATSINSTITUITION", -# "KUBSBELI", -# "VIRKTYP2", -# "LANDTYP", -# "ARE1", -# "BR19A2", -# "ENERGI1", -# "PVARMEKILDE", -# "AARSFORBRUG", -# "PRISDEFINITION", -# "ENERGIENHED", -# "TILANV", -# "TILGANG", -# "MULT", -# "ANVEND1", -# "EMTYPE8", -# "OVERPOST", -# "OPPRINCIP", -# "ENERGIKILDE", -# "ANVENDTYPE", -# "UDLEDBRANCHE", -# "UDLEDLAND", -# "BRANCHEAFTRYK1", -# "BEHANDLING", -# "AFFFRAK", -# "FARLIG", -# "VANDTYP", -# "INDKAT", -# "UDL", -# "MFORMAAL", -# "KATEGORI", -# "MILJOKAT", -# "SKATTEART", -# "BALPOST", -# "OEKOSTATUS", -# "VARTYP", -# "MÆNGDE6", -# "KUNDEGRP" -# ) -# -# -# -# -# -# "TILKOMMUNE", -# "FRAKOMMUNE", - - # Create the nested list structure komgrp <- list( "1 Hovedstadskommuner" = list( From 6519cc151881274539c3ab8908928f35afac1d51 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:43:41 +0100 Subject: [PATCH 11/28] Add cyclocomp --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d75b6c5..711054e 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -23,7 +23,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: cache-version: 2 - extra-packages: any::lintr, local::. + extra-packages: any::lintr, any::cyclocomp, local::. needs: lint - name: Lint From 9327c5a4ad530a09cb1e972855199e80c71035ea Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:46:22 +0100 Subject: [PATCH 12/28] Add geodk instal --- .github/workflows/R-CMD-check.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index bcdf126..60cac05 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -2,7 +2,7 @@ # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: main + branches: [ main ] pull_request: workflow_dispatch: schedule: @@ -37,6 +37,19 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Enable r-universe repo + run: | + options(repos = c( + ropengov = 'https://ropengov.r-universe.dev', + CRAN = 'https://cloud.r-project.org' + )) + shell: Rscript {0} + + - name: Install package from r-universe + run: | + install.packages('geodk') + shell: Rscript {0} + - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r@v2 From 8d9e7a6984154684663d47a3bc5b43eb80658d27 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:47:47 +0100 Subject: [PATCH 13/28] Move custom r commands to a step after the r installation itself This was a silly one --- .github/workflows/R-CMD-check.yaml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 60cac05..ebbcb04 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -37,18 +37,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Enable r-universe repo - run: | - options(repos = c( - ropengov = 'https://ropengov.r-universe.dev', - CRAN = 'https://cloud.r-project.org' - )) - shell: Rscript {0} - - - name: Install package from r-universe - run: | - install.packages('geodk') - shell: Rscript {0} - uses: r-lib/actions/setup-pandoc@v2 @@ -66,6 +54,19 @@ jobs: needs: | check + - name: Enable r-universe repo + run: | + options(repos = c( + ropengov = 'https://ropengov.r-universe.dev', + CRAN = 'https://cloud.r-project.org' + )) + shell: Rscript {0} + + - name: Install package from r-universe + run: | + install.packages('geodk') + shell: Rscript {0} + - uses: r-lib/actions/check-r-package@v2 with: upload-snapshots: true From 3f6adb12d106f70b66fbc28787f839824e5f046b Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:52:21 +0100 Subject: [PATCH 14/28] Specify r universe repo in install command --- .github/workflows/R-CMD-check.yaml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index ebbcb04..80d238a 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -54,17 +54,9 @@ jobs: needs: | check - - name: Enable r-universe repo - run: | - options(repos = c( - ropengov = 'https://ropengov.r-universe.dev', - CRAN = 'https://cloud.r-project.org' - )) - shell: Rscript {0} - - name: Install package from r-universe run: | - install.packages('geodk') + install.packages('geodk', repos = c('https://ropengov.r-universe.dev', 'https://cloud.r-project.org')) shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 From 13b6a5ac5b9829793e7c8edc0806030271e716c2 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 18:57:38 +0100 Subject: [PATCH 15/28] Install from github instead --- .github/workflows/R-CMD-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 80d238a..1fb541c 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -56,7 +56,7 @@ jobs: - name: Install package from r-universe run: | - install.packages('geodk', repos = c('https://ropengov.r-universe.dev', 'https://cloud.r-project.org')) + renv::install_github("rOpenGov/geodk") shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 From 7cdf2cd3163c777b28c554fa64d3c528484cb1f3 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:00:47 +0100 Subject: [PATCH 16/28] Use the right function --- .github/workflows/R-CMD-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 1fb541c..ff8c20a 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -56,7 +56,7 @@ jobs: - name: Install package from r-universe run: | - renv::install_github("rOpenGov/geodk") + renv::install("rOpenGov/geodk") shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 From 52f854fddd536385012db5bdf297ad21cadc3cfa Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:01:46 +0100 Subject: [PATCH 17/28] Add test for each constructor class --- tests/testthat/test-s3_constructors.R | 159 ++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 tests/testthat/test-s3_constructors.R diff --git a/tests/testthat/test-s3_constructors.R b/tests/testthat/test-s3_constructors.R new file mode 100644 index 0000000..5e4debf --- /dev/null +++ b/tests/testthat/test-s3_constructors.R @@ -0,0 +1,159 @@ +test_that("new_dkstat_Denmark_municipality_07 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Denmark_municipality_07() + + expect_s3_class(df, "dkstat_Denmark_municipality_07") +}) + +test_that("new_dkstat_KOMGRP assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_KOMGRP() + + expect_s3_class(df, "dkstat_KOMGRP") +}) + +test_that("new_dkstat_kom_omraade assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_kom_omraade() + + expect_s3_class(df, "dkstat_kom_omraade") +}) + +test_that("new_dkstat_Verden_dk2 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Verden_dk2() + + expect_s3_class(df, "dkstat_Verden_dk2") +}) + +test_that("new_dkstat_denmark_cities_19 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_denmark_cities_19() + + expect_s3_class(df, "dkstat_denmark_cities_19") +}) + +test_that("new_dkstat_denmark_parish_23_4c assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_denmark_parish_23_4c() + + expect_s3_class(df, "dkstat_denmark_parish_23_4c") +}) + +test_that("new_dkstat_denmark_municipalitygroups_24 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_denmark_municipalitygroups_24() + + expect_s3_class(df, "dkstat_denmark_municipalitygroups_24") +}) + +test_that("new_dkstat_Denmark_region_07 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Denmark_region_07() + + expect_s3_class(df, "dkstat_Denmark_region_07") +}) + +test_that("new_dkstat_Denmark_rural_07 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Denmark_rural_07() + + expect_s3_class(df, "dkstat_Denmark_rural_07") +}) + +test_that("new_dkstat_denmark_multimember_constituency_23 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_denmark_multimember_constituency_23() + + expect_s3_class(df, "dkstat_denmark_multimember_constituency_23") +}) + +test_that("new_dkstat_denmark_deanary_23 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_denmark_deanary_23() + + expect_s3_class(df, "dkstat_denmark_deanary_23") +}) + +test_that("new_dkstat_europe_dk assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_europe_dk() + + expect_s3_class(df, "dkstat_europe_dk") +}) + +test_that("new_dkstat_Verden_dk assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Verden_dk() + + expect_s3_class(df, "dkstat_Verden_dk") +}) + +test_that("new_dkstat_Europa_DK3 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Europa_DK3() + + expect_s3_class(df, "dkstat_Europa_DK3") +}) + +test_that("new_dkstat_Denmark_county assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Denmark_county() + + expect_s3_class(df, "dkstat_Denmark_county") +}) + +test_that("new_dkstat_Verden_dk4 assigns the class properly", { + df <- data.frame( + x = 1:999, + y = 999:1 + ) |> + new_dkstat_Verden_dk4() + + expect_s3_class(df, "dkstat_Verden_dk4") +}) From 55fd6e0b71bff9f83aab2f5b41dae47f4b234db4 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:18:19 +0100 Subject: [PATCH 18/28] Rename function --- ..._properties.R => determine_geo_properties.R} | 17 +++++++---------- R/dst_get_data.R | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) rename R/{determine_geographic_properties.R => determine_geo_properties.R} (77%) diff --git a/R/determine_geographic_properties.R b/R/determine_geo_properties.R similarity index 77% rename from R/determine_geographic_properties.R rename to R/determine_geo_properties.R index b453898..c752f91 100644 --- a/R/determine_geographic_properties.R +++ b/R/determine_geo_properties.R @@ -1,9 +1,9 @@ -# determine_geographic_properties.R +# determine_geo_properties.R # This file contains the logic to decide what kind of geographic information is # included in a given dataset. The function is mainly used in # `dst_get_data()` - Thus affecting `dst_get_all_data()` -determine_geographic_properties <- function(table, df) { +determine_geo_properties <- function(table, df) { clnms <- colnames(df) meta <- dst_meta(table, lang = "da", geo = TRUE) @@ -12,28 +12,25 @@ determine_geographic_properties <- function(table, df) { chosen_constructor <- choose_geo_class(meta) chosen_constructor(df) } else { - return(df) + df } } # Check if the metadata indicates a geographic variable is_geographic <- function(meta) { if (is.null(meta)) { - return(FALSE) + FALSE } else if (!is.null(meta)) { - return(TRUE) + TRUE } } # Choose a class constructor choose_geo_class <- function(meta) { - # Get the map variable meta_class <- meta$variables$map # Paste class constructor name prefix with class name and get function - func <- paste0("new_dkstat_", meta_class) |> get() - - return(func) - + paste0("new_dkstat_", meta_class) |> + get() } diff --git a/R/dst_get_data.R b/R/dst_get_data.R index 706d40b..5c38341 100644 --- a/R/dst_get_data.R +++ b/R/dst_get_data.R @@ -133,7 +133,7 @@ dst_get_data <- function(table, dst_data$TID <- dst_date_parse(dst_date = dst_data$TID) } - data <- determine_geographic_properties(table, dst_data) + data <- determine_geo_properties(table, dst_data) return(data) } From a871bdaa773d7c74c335aeab788ae7833cb70d9f Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:20:54 +0100 Subject: [PATCH 19/28] Remove lint and loosen linting settings a bit --- .lintr | 8 ++++++-- R/dst_get_all_data.R | 1 - R/dst_meta_map.R | 11 +++-------- data-raw/dkstat_groups.R | 9 +++++++-- data-raw/dst_map.R | 1 - 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.lintr b/.lintr index 42a3ead..12148bf 100644 --- a/.lintr +++ b/.lintr @@ -1,5 +1,9 @@ linters: linters_with_defaults( - cyclocomp_linter(complexity_limit = 17L)) + cyclocomp_linter(complexity_limit = 17L), + object_usage_linter = NULL, + return_linter = NULL) encoding: "UTF-8" exclusions: list( - "tests") + "tests", + "vignettes", + "R/s3_constructors.R") diff --git a/R/dst_get_all_data.R b/R/dst_get_all_data.R index 012a3f4..d1cc23a 100644 --- a/R/dst_get_all_data.R +++ b/R/dst_get_all_data.R @@ -28,7 +28,6 @@ dst_get_all_data <- function(table, lang = "da", parse_dst_tid = TRUE) { table = table, query = query, lang = lang, - # format = "BULK", parse_dst_tid = parse_dst_tid ) diff --git a/R/dst_meta_map.R b/R/dst_meta_map.R index 8ef1aac..4f3d1a0 100644 --- a/R/dst_meta_map.R +++ b/R/dst_meta_map.R @@ -18,17 +18,12 @@ dst_meta_map <- function(meta, lang) { # Get the description of the variables. # If map does not exist, we return a NULL - if (!"map" %in% colnames(meta[["variables"]])) {return(NULL)} + if (!"map" %in% colnames(meta[["variables"]])) { + return(NULL) + } variables <- meta[["variables"]][, c("id", "text", "map")] |> na.omit() - # Structure the values the user can choose in their query - # values <- meta[["variables"]][, "values"] - # names(values) <- variables$id - - # Retrieve the geographic levels - # values <- values[names(values) %in% variables$id] - # Return the data as a list. return(list( "basics" = basics, diff --git a/data-raw/dkstat_groups.R b/data-raw/dkstat_groups.R index f0b851d..dc0a1bf 100644 --- a/data-raw/dkstat_groups.R +++ b/data-raw/dkstat_groups.R @@ -15,7 +15,7 @@ create_groups <- function(x) { id <- 0 groups <- numeric(nrow(x)) - for (i in 1:nrow(x)) { + for (i in seq_len(x)) { if (x$NIVEAU[i] == 1) { id <- id + 1 } @@ -161,4 +161,9 @@ kom_omraade <- c( "851 Aalborg" ) -usethis::use_data(kom_omraade, compress = "xz", overwrite = TRUE, internal = TRUE) +usethis::use_data( + kom_omraade, + compress = "xz", + overwrite = TRUE, + internal = TRUE +) diff --git a/data-raw/dst_map.R b/data-raw/dst_map.R index 82d119d..d4a5aa0 100644 --- a/data-raw/dst_map.R +++ b/data-raw/dst_map.R @@ -27,7 +27,6 @@ get_meta <- function(table, lang = "da") { # Get all tables tbls <- dst_get_tables()$id -# tbls <- c("laby04", "vandud") # Define empty map list maps <- list() From 0974c730d2bdfdffcb77b1139f0c87b428b90a01 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:22:19 +0100 Subject: [PATCH 20/28] Install with remotes package --- .github/workflows/R-CMD-check.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index ff8c20a..7a12420 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -56,7 +56,8 @@ jobs: - name: Install package from r-universe run: | - renv::install("rOpenGov/geodk") + install.packages("remotes") + remotes::install_github("rOpenGov/geodk") shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 From 6a58e4cbde3ae4dc71da0436ae75a178251d2929 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:26:26 +0100 Subject: [PATCH 21/28] Install package from runiverse --- .github/workflows/R-CMD-check.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 7a12420..28ea48b 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -45,20 +45,23 @@ jobs: r-version: ${{ matrix.config.r }} http-user-agent: ${{ matrix.config.http-user-agent }} use-public-rspm: true + extra-repositories: | + https://ropengov.r-universe.dev - uses: r-lib/actions/setup-r-dependencies@v2 with: cache-version: 3 extra-packages: | any::rcmdcheck + any::geodk needs: | check - - name: Install package from r-universe - run: | - install.packages("remotes") - remotes::install_github("rOpenGov/geodk") - shell: Rscript {0} + # - name: Install package from r-universe + # run: | + # install.packages("remotes") + # remotes::install_github("rOpenGov/geodk") + # shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 with: From 63b933f0da19e4133a89227747e647e156423918 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:29:23 +0100 Subject: [PATCH 22/28] Add tidyverse --- .github/workflows/R-CMD-check.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 28ea48b..542e9c9 100755 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -54,6 +54,7 @@ jobs: extra-packages: | any::rcmdcheck any::geodk + any::tidyverse needs: | check From 7f9cb0e4d193508365f6830116899a5d01b29197 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:33:33 +0100 Subject: [PATCH 23/28] Try to fix cmd check --- vignettes/tech-specs-for-geodk.Rmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vignettes/tech-specs-for-geodk.Rmd b/vignettes/tech-specs-for-geodk.Rmd index 88369c1..73c0acd 100644 --- a/vignettes/tech-specs-for-geodk.Rmd +++ b/vignettes/tech-specs-for-geodk.Rmd @@ -24,7 +24,7 @@ library(tidyverse) # What is this? -This documents the technical specification for the integration between `{dkstat}` and `{geodk}`. It can be found on this page and in [the `{geodk}` documentation](https://ropengov.github.io/geodk/articles/tech-specs-for-dkstat.html). `vignette("tech-specs-for-dkstat", package = "geodk")`. +This documents the technical specification for the integration between `{dkstat}` and `{geodk}`. It can be found on this page and in [the `{geodk}` documentation](https://ropengov.github.io/geodk/articles/tech-specs-for-dkstat.html). vignette("tech-specs-for-dkstat", package = "geodk"). ## Why would you want to read this? @@ -32,7 +32,7 @@ I honestly don't know. This document is written mostly for me [(Aleksander)](htt # Integration usage -A thorough usage guide can be found in `vignette("geodk", package = "dkstat")`, but below I will provide a technical walkthrough of the integration. +A thorough usage guide can be found in vignette("geodk", package = "dkstat"), but below I will provide a technical walkthrough of the integration. ## Main goal From 600067c8b8175efddb63e7ee66c0caa94e721c05 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:38:12 +0100 Subject: [PATCH 24/28] Dont eval --- vignettes/tech-specs-for-geodk.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/tech-specs-for-geodk.Rmd b/vignettes/tech-specs-for-geodk.Rmd index 73c0acd..a809e92 100644 --- a/vignettes/tech-specs-for-geodk.Rmd +++ b/vignettes/tech-specs-for-geodk.Rmd @@ -15,7 +15,7 @@ knitr::opts_chunk$set( ) ``` -```{r setup, include = FALSE} +```{r setup, include = FALSE, eval = FALSE} library(dkstat) library(geodk) library(tidyverse) From abf1f541c98380204c2758a182aa5a2e52305412 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:41:07 +0100 Subject: [PATCH 25/28] More things --- vignettes/tech-specs-for-geodk.Rmd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vignettes/tech-specs-for-geodk.Rmd b/vignettes/tech-specs-for-geodk.Rmd index a809e92..6fa2497 100644 --- a/vignettes/tech-specs-for-geodk.Rmd +++ b/vignettes/tech-specs-for-geodk.Rmd @@ -19,7 +19,6 @@ knitr::opts_chunk$set( library(dkstat) library(geodk) library(tidyverse) -# library(ggflowchart) ``` # What is this? @@ -49,7 +48,7 @@ When accessing data from a table, e.g. "laby04" there is no obvious way to know ```{r} dkstat::dst_get_all_data("laby01") |> - distinct(KOMGRP, .keep_all = TRUE) |> + dplyr::distinct(KOMGRP, .keep_all = TRUE) |> tail() ``` From 3ac876209402ba5d81f75917a44733c398b9bfce Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:44:19 +0100 Subject: [PATCH 26/28] Declare import --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8e168ec..c433b67 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,8 @@ Imports: Suggests: knitr, rmarkdown, - testthat + testthat, + dplyr Encoding: UTF-8 Roxygen: list(markdown = TRUE) Config/testthat/edition: 3 From b6391e8b36bf713652748daf50e34e22da9c20fe Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:45:01 +0100 Subject: [PATCH 27/28] Increment versions and date --- DESCRIPTION | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c433b67..1d2d478 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Type: Package Package: dkstat Title: API connection to the StatBank from Statistics Denmark -Version: 0.0.0.9001 -Date: 2024-12-10 +Version: 0.0.0.9002 +Date: 2025-02-25 Authors@R: c( person("Aleksander", "Bang-Larsen", , "contact@aleksanderbl.dk", role = c("aut", "cre"), comment = c(ORCID = "0009-0007-7984-4650")), @@ -34,6 +34,6 @@ RoxygenNote: 7.3.2 X-schema.org-isPartOf: http://ropengov.org/ X-schema.org-keywords: ropengov Depends: - R (>= 3.5) + R (>= 4.1) LazyData: true VignetteBuilder: knitr From 0f38c5a28d16093022ea27ee9c07b51e2aa4c217 Mon Sep 17 00:00:00 2001 From: aleksanderbl29 Date: Tue, 25 Feb 2025 19:48:24 +0100 Subject: [PATCH 28/28] Remove unused utils file It also contained a lot of non-ASCII chars --- R/utils.R | 261 ------------------------------------------------------ 1 file changed, 261 deletions(-) delete mode 100644 R/utils.R diff --git a/R/utils.R b/R/utils.R deleted file mode 100644 index 2a4d691..0000000 --- a/R/utils.R +++ /dev/null @@ -1,261 +0,0 @@ - - - -geo_vars <- c( - "OMRÅDE", - "HOVEDDELE", - "BYER", - "KOMK", - "OER", - "PNR20", # Postal code - "SOGN", - "KOMGRP", - "REGLAND", - "KOMMUNEDK", - "LANDSDEL", - "OMR20", - "AMT", - "BEBO", - "REGION", - "BOPREG", - "BOP", - "PROVSTI", - "BOPKOM", - "BOPOMR", - "LONGRP", - "BOPLANDK", - "BOPKOMGRP", - "KMDR", - "LANDDEL" -) - -# Create the nested list structure -komgrp <- list( - "1 Hovedstadskommuner" = list( - "101 København" = "København", - "147 Frederiksberg" = "Frederiksberg", - "151 Ballerup" = "Ballerup", - "153 Brøndby" = "Brøndby", - "155 Dragør" = "Dragør", - "157 Gentofte" = "Gentofte", - "159 Gladsaxe" = "Gladsaxe", - "161 Glostrup" = "Glostrup", - "163 Herlev" = "Herlev", - "165 Albertslund" = "Albertslund", - "167 Hvidovre" = "Hvidovre", - "169 Høje-Taastrup" = "Høje-Taastrup", - "173 Lyngby-Taarbæk" = "Lyngby-Taarbæk", - "175 Rødovre" = "Rødovre", - "183 Ishøj" = "Ishøj", - "185 Tårnby" = "Tårnby", - "187 Vallensbæk" = "Vallensbæk", - "190 Furesø" = "Furesø", - "201 Allerød" = "Allerød", - "223 Hørsholm" = "Hørsholm", - "230 Rudersdal" = "Rudersdal", - "240 Egedal" = "Egedal", - "253 Greve" = "Greve", - "269 Solrød" = "Solrød" - ), - - "2 Storbykommuner" = list( - "461 Odense" = "Odense", - "751 Aarhus" = "Aarhus", - "851 Aalborg" = "Aalborg" - ), - - "3 Provinsbykommuner" = list( - "217 Helsingør" = "Helsingør", - "219 Hillerød" = "Hillerød", - "259 Køge" = "Køge", - "265 Roskilde" = "Roskilde", - "330 Slagelse" = "Slagelse", - "370 Næstved" = "Næstved", - "561 Esbjerg" = "Esbjerg", - "607 Fredericia" = "Fredericia", - "615 Horsens" = "Horsens", - "621 Kolding" = "Kolding", - "630 Vejle" = "Vejle", - "657 Herning" = "Herning", - "661 Holstebro" = "Holstebro", - "730 Randers" = "Randers", - "740 Silkeborg" = "Silkeborg", - "791 Viborg" = "Viborg" - ), - - "4 Oplandskommuner" = list( - "210 Fredensborg" = "Fredensborg", - "250 Frederikssund" = "Frederikssund", - "260 Halsnæs" = "Halsnæs", - "270 Gribskov" = "Gribskov", - "316 Holbæk" = "Holbæk", - "320 Faxe" = "Faxe", - "329 Ringsted" = "Ringsted", - "336 Stevns" = "Stevns", - "340 Sorø" = "Sorø", - "350 Lejre" = "Lejre", - "410 Middelfart" = "Middelfart", - "420 Assens" = "Assens", - "430 Faaborg-Midtfyn" = "Faaborg-Midtfyn", - "440 Kerteminde" = "Kerteminde", - "450 Nyborg" = "Nyborg", - "480 Nordfyns" = "Nordfyns", - "575 Vejen" = "Vejen", - "706 Syddjurs" = "Syddjurs", - "710 Favrskov" = "Favrskov", - "727 Odder" = "Odder", - "746 Skanderborg" = "Skanderborg", - "756 Ikast-Brande" = "Ikast-Brande", - "766 Hedensted" = "Hedensted", - "840 Rebild" = "Rebild" - ), - - "5 Landkommuner" = list( - "306 Odsherred" = "Odsherred", - "326 Kalundborg" = "Kalundborg", - "360 Lolland" = "Lolland", - "376 Guldborgsund" = "Guldborgsund", - "390 Vordingborg" = "Vordingborg", - "400 Bornholm" = "Bornholm", - "479 Svendborg" = "Svendborg", - "482 Langeland" = "Langeland", - "492 Ærø" = "Ærø", - "510 Haderslev" = "Haderslev", - "530 Billund" = "Billund", - "540 Sønderborg" = "Sønderborg", - "550 Tønder" = "Tønder", - "563 Fanø" = "Fanø", - "573 Varde" = "Varde", - "580 Aabenraa" = "Aabenraa", - "665 Lemvig" = "Lemvig", - "671 Struer" = "Struer", - "707 Norddjurs" = "Norddjurs", - "741 Samsø" = "Samsø", - "760 Ringkøbing-Skjern" = "Ringkøbing-Skjern", - "773 Morsø" = "Morsø", - "779 Skive" = "Skive", - "787 Thisted" = "Thisted", - "810 Brønderslev" = "Brønderslev", - "813 Frederikshavn" = "Frederikshavn", - "820 Vesthimmerlands" = "Vesthimmerlands", - "825 Læsø" = "Læsø", - "846 Mariagerfjord" = "Mariagerfjord", - "849 Jammerbugt" = "Jammerbugt", - "860 Hjørring" = "Hjørring" - ) -) - - -kom_omraade <- c( - "000 Hele landet", - "1 Hovedstadskommuner", - "2 Storbykommuner", - "3 Provinsbykommuner", - "4 Oplandskommuner", - "5 Landkommuner", - "101 København", - "147 Frederiksberg", - "155 Dragør", - "185 Tårnby", - "165 Albertslund", - "151 Ballerup", - "153 Brøndby", - "157 Gentofte", - "159 Gladsaxe", - "161 Glostrup", - "163 Herlev", - "167 Hvidovre", - "169 Høje-Taastrup", - "183 Ishøj", - "173 Lyngby-Taarbæk", - "175 Rødovre", - "187 Vallensbæk", - "201 Allerød", - "240 Egedal", - "210 Fredensborg", - "250 Frederikssund", - "190 Furesø", - "270 Gribskov", - "260 Halsnæs", - "217 Helsingør", - "219 Hillerød", - "223 Hørsholm", - "230 Rudersdal", - "400 Bornholm", - "411 Christiansø", - "253 Greve", - "259 Køge", - "350 Lejre", - "265 Roskilde", - "269 Solrød", - "320 Faxe", - "376 Guldborgsund", - "316 Holbæk", - "326 Kalundborg", - "360 Lolland", - "370 Næstved", - "306 Odsherred", - "329 Ringsted", - "330 Slagelse", - "340 Sorø", - "336 Stevns", - "390 Vordingborg", - "420 Assens", - "430 Faaborg-Midtfyn", - "440 Kerteminde", - "482 Langeland", - "410 Middelfart", - "480 Nordfyns", - "450 Nyborg", - "461 Odense", - "479 Svendborg", - "492 Ærø", - "530 Billund", - "561 Esbjerg", - "563 Fanø", - "607 Fredericia", - "510 Haderslev", - "621 Kolding", - "540 Sønderborg", - "550 Tønder", - "573 Varde", - "575 Vejen", - "630 Vejle", - "580 Aabenraa", - "710 Favrskov", - "766 Hedensted", - "615 Horsens", - "707 Norddjurs", - "727 Odder", - "730 Randers", - "741 Samsø", - "740 Silkeborg", - "746 Skanderborg", - "706 Syddjurs", - "751 Aarhus", - "657 Herning", - "661 Holstebro", - "756 Ikast-Brande", - "665 Lemvig", - "760 Ringkøbing-Skjern", - "779 Skive", - "671 Struer", - "791 Viborg", - "810 Brønderslev", - "813 Frederikshavn", - "860 Hjørring", - "849 Jammerbugt", - "825 Læsø", - "846 Mariagerfjord", - "773 Morsø", - "840 Rebild", - "787 Thisted", - "820 Vesthimmerlands", - "851 Aalborg" -) - - -geographic_vectors <- list( - "komgrp" = komgrp, - "kom_omraade" = kom_omraade -)