class: middle, right, title-slide # Using nettskjemar ## - for transparent data flows - ### Athanasia Monika Mowinckel ### 03.06.2021 --- background-image: url("https://drmowinckels.io/about/profile.png") background-position: right bottom background-size: auto 100% class: middle, dark .pull-left[ ## Athanasia Monika Mowinckel [<i class="fa fa-twitter fa-2x" aria-hidden="true"></i> @DrMowinckels](https://twitter.com/DrMowinckels) [<i class="fa fa-github fa-2x" aria-hidden="true"></i> Athanasiamo](https://github.com/Athanasiamo) [<i class="fa fa-globe fa-2x" aria-hidden="true"></i> drmowinckels.io/](https://drmowinckels.io/) - Staff scientist - PhD in cognitive psychology - Software Carpentry Instructor ] --- layout: true <div class="my-sidebar"></div> --- # What is Nettskjema? - self-service survey tool developed by UiO -- - can be used for simple questionnaires, sign up forms, and multiple choice -- - can be used for collecting sensitive data (connects to TSD) -- - a high degree of security and privacy -- - designed for accessibility .footnote[ source: [Nettskjema UiO webpages](https://www.uio.no/english/services/it/adm-services/nettskjema/) ] --- # What do we use nettskjema for? - questionnaires sent to participants -- - "punching" data from in-person tests -- - test / mri logs -- - file uploader for collaborators directly to TSD -- - digital consent forms using ID-porten -- - automatic data upload from test-computers to TSD through the API --- # The nettskjema portal .pull-left[ - where you can create new forms in an interactive builder - where you can set settings for your form, like access rights, response types etc. - where you can download responses, codebook and SPSS syntax for data conversion ] -- .pull-right[ - has a limitation of number of responses it can download (~ 1500) - has limited meta-data to the forms - if you have many forms active you want data from, data retrieval can be cumbersome ] --- # The nettskjema API -- .pull-left[ ### What is an API? - application programming interface, a way to programatically interact with a service or program - enables us to interact with nettskjema through programs like python, R, bash etc. - makes it possible to create automatic pipelines for data handling ] -- .pull-right[ ### What can we do? - pull information - about forms (meta-data and codebooks) - response data - push information - create forms automatically - push data automatically to an existing form ] --- # What do we need? .pull-left[ - an API user - a special instance of your uio username that you specifically grant access to your forms ] -- .pull-right[ - an API access token - which grants you secure access to the forms that you have provided api-user access to ] --- class: middle, center, dark # Live demo ## open RStudio ??? ```r library(nettskjemar) nettskjema_user_create() nettskjema_token2renviron("token", "testapi") nettskjema_renviron_edit() nettskjema_token_expiry() ``` - use uio username for main API access user - the `nettskjema_token2renviron()` opens your user Rprofile, or creates it if it does not exist. It also makes sure this file is only readable by your user. - keep your token safe! This token enables access to forms the corresponding API user has access to. Treat it as a secure password. --- class: center, dark # Exercise ## Create an API user and add the access token to your Renviron ## Check your IP address on [whatismyipaddress.com](https://whatismyipaddress.com/)
10
:
00
--- # How do we access the data? - we have now our user _and_ token - we need to give our API user access to the forms we want API access from ??? This process of having a separate API and uio user is cumbersome, but that is how the system is set up now. I know USIT are working on a potential other solution, but that is not available now. So we need to make sure our API user has access to all the forms we want it to have access to. --- # Get nettskjemar dev-version A bug in the code found while working on this workshop was fixed yesterday. To work with the newest version of this package install by ```r # Enable my development universe options(repos = c( athanasiamo = 'https://athanasiamo.r-universe.dev', CRAN = 'https://cloud.r-project.org')) # Install it install.packages('nettskjemar') ``` --- class: middle, center, inverse # Answer the test form! ## [https://nettskjema.no/a/205451](https://nettskjema.no/a/205451) --- class: middle, center, dark # Live demo ## Go to [nettskjema.no](https://nettskjema.no/user/form/preview.html?id=205451#/) ??? Add inn all course users based on your cheat sheet. everyone should have access to this form, make note of the nettskjema ID in the url. --- # Accessing the data ```r library(nettskjemar) nettskjema_get_data(205451) ``` ``` ## Form 205451 has 3 responses to download. ``` ``` ## # A tibble: 3 x 8 ## form_id submission_id ncourse_01 ncourse_02 ncourse_03 ncourse_04 ncourse_05 ## <dbl> <chr> <chr> <chr> <chr> <chr> <chr> ## 1 205451 14353700 coffee coffee humans humans 2 ## 2 205451 14353693 food coffee humans dolphins 5 ## 3 205451 14353688 42 towel dolphins;mi… dolphins 4 ## # … with 1 more variable: ncourse_06 <chr> ``` ??? data! Notice that we have the data according to the codebook. --- # Accessing the data ### working with checkboxes ```r nettskjema_get_data(205451, checkbox_delim = "-") ``` ``` ## Form 205451 has 3 responses to download. ``` ``` ## # A tibble: 3 x 8 ## form_id submission_id ncourse_01 ncourse_02 ncourse_03 ncourse_04 ncourse_05 ## <dbl> <chr> <chr> <chr> <chr> <chr> <chr> ## 1 205451 14353700 coffee coffee humans humans 2 ## 2 205451 14353693 food coffee humans dolphins 5 ## 3 205451 14353688 42 towel dolphins-mi… dolphins 4 ## # … with 1 more variable: ncourse_06 <chr> ``` ??? This default can be altered through an extra argument. --- # Accessing the data ### working with checkboxes ```r library(tidyverse) ``` ``` ## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ── ``` ``` ## ✓ ggplot2 3.3.3 ✓ purrr 0.3.4 ## ✓ tibble 3.1.2 ✓ dplyr 1.0.6 ## ✓ tidyr 1.1.3 ✓ stringr 1.4.0 ## ✓ readr 1.4.0 ✓ forcats 0.5.1 ``` ``` ## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ── ## x dplyr::filter() masks stats::filter() ## x dplyr::lag() masks stats::lag() ``` ```r nettskjema_get_data(205451, checkbox_type = "list") %>% unnest(ncourse_03) ``` ``` ## Form 205451 has 3 responses to download. ``` ``` ## # A tibble: 4 x 8 ## form_id submission_id ncourse_01 ncourse_02 ncourse_03 ncourse_04 ncourse_05 ## <dbl> <chr> <chr> <chr> <chr> <chr> <chr> ## 1 205451 14353700 coffee coffee humans humans 2 ## 2 205451 14353693 food coffee humans dolphins 5 ## 3 205451 14353688 42 towel dolphins dolphins 4 ## 4 205451 14353688 42 towel mice dolphins 4 ## # … with 1 more variable: ncourse_06 <chr> ``` ??? There is a checkbox type of "list", which correctly returns the values chosen as a list. When this type is unnested, you actually get more row per submission ID, because the number of chosen boxes for a participant gets expanded into several unique rows. --- # Accessing the data .pull-left[ ### working with checkboxes ```r nettskjema_get_data(205451, checkbox_type = "list") %>% unnest(ncourse_03) %>% ggplot(aes(x = ncourse_03)) + geom_bar() ``` ] .pull-right[ ``` ## Form 205451 has 3 responses to download. ``` ![](index_files/figure-html/unnamed-chunk-5-1.png)<!-- --> ] ??? This can be convenient when, for instance making a histogram in ggplot2, which automatically counts the number of occurrences of a variable. --- # Accessing the data ### working with checkboxes ```r nettskjema_get_data(205451, checkbox_type = "columns") ``` ``` ## Form 205451 has 3 responses to download. ``` ``` ## # A tibble: 3 x 10 ## form_id submission_id ncourse_01 ncourse_02 ncourse_03_dolph… ncourse_03_huma… ## <dbl> <chr> <chr> <chr> <dbl> <dbl> ## 1 205451 14353700 coffee coffee 0 1 ## 2 205451 14353693 food coffee 0 1 ## 3 205451 14353688 42 towel 1 0 ## # … with 4 more variables: ncourse_03_mice <dbl>, ncourse_04 <chr>, ## # ncourse_05 <chr>, ncourse_06 <chr> ``` ??? The last checkbox type returns each answer option as its own binary column. This is more similar to what the nettskjema portal does, and might be more familiar to many. What is great through the API is that we now have a choice in how we would prefer the data do be returned. --- # Accessing the data ### adding dummy codes ```r nettskjema_get_data(205451, information = list(dummy = "order", text = "option")) ``` ``` ## Form 205451 has 3 responses to download. ``` ``` ## # A tibble: 3 x 18 ## form_id submission_id ncourse_01 ncourse_01_dummy ncourse_01_text ncourse_02 ## <dbl> <chr> <chr> <chr> <chr> <chr> ## 1 205451 14353700 coffee 4 Coffee coffee ## 2 205451 14353693 food 1 Food coffee ## 3 205451 14353688 42 2 42 towel ## # … with 12 more variables: ncourse_02_dummy <chr>, ncourse_02_text <chr>, ## # ncourse_03 <chr>, ncourse_03_dummy <chr>, ncourse_03_text <chr>, ## # ncourse_04 <chr>, ncourse_04_dummy <chr>, ncourse_04_text <chr>, ## # ncourse_05 <chr>, ncourse_05_dummy <chr>, ncourse_05_text <chr>, ## # ncourse_06 <chr> ``` --- # Saving the data ```r galaxy <- nettskjema_get_data(205451) ``` ``` ## Form 205451 has 3 responses to download. ``` ```r write.table(galaxy, "data/data_2021_06_03.tsv", sep="\t", row.names = FALSE) ``` --- class: center, dark # Exercise ## Give your API user access to one of your own forms and access the data from this form
10
:
00
--- # Accessing other form information ### codebooks ```r nettskjema_get_codebook(205451) ``` ``` ## # A tibble: 20 x 15 ## form_id element_no question question_descr question_codebo… question_mandat… ## * <dbl> <chr> <chr> <chr> <chr> <lgl> ## 1 205451 3 What is … <NA> ncourse_01 FALSE ## 2 205451 3 What is … <NA> ncourse_01 FALSE ## 3 205451 3 What is … <NA> ncourse_01 FALSE ## 4 205451 3 What is … <NA> ncourse_01 FALSE ## 5 205451 3 What sho… <NA> ncourse_02 TRUE ## 6 205451 3 What sho… <NA> ncourse_02 TRUE ## 7 205451 3 What sho… <NA> ncourse_02 TRUE ## 8 205451 3 What sho… <NA> ncourse_02 TRUE ## 9 205451 4 Who are … <NA> ncourse_03 FALSE ## 10 205451 4 Who are … <NA> ncourse_03 FALSE ## 11 205451 4 Who are … <NA> ncourse_03 FALSE ## 12 205451 4 Which sp… <NA> ncourse_04 FALSE ## 13 205451 4 Which sp… <NA> ncourse_04 FALSE ## 14 205451 4 Which sp… <NA> ncourse_04 FALSE ## 15 205451 5 Which bo… <NA> ncourse_05 FALSE ## 16 205451 5 Which bo… <NA> ncourse_05 FALSE ## 17 205451 5 Which bo… <NA> ncourse_05 FALSE ## 18 205451 5 Which bo… <NA> ncourse_05 FALSE ## 19 205451 5 Which bo… <NA> ncourse_05 FALSE ## 20 205451 6 Do you h… <NA> ncourse_06 FALSE ## # … with 9 more variables: question_order <int>, answer_order <chr>, ## # answer_option <chr>, answer_codebook <chr>, answer_preselected <lgl>, ## # answer_correct <lgl>, max_selected <int>, question_preselected <lgl>, ## # question_rangemarks <lgl> ``` --- # Accessing other form information ### codebooks ```r nettskjema_get_codebook(205451, as_is = TRUE) ``` ``` ## # Nettskjema raw codebook for form 205451 ## ## no. questions: 6 ## no. answers: 12 ``` --- # Accessing other form information ### codebooks ```r nettskjema_get_codebook(205451, as_is = TRUE) %>% nettskjema_write_codebook("data/codebook_205451.json") nettskjema_get_codebook(205451) %>% nettskjema_write_codebook("data/codebook_205451.tsv") ``` --- # Accessing other form information ### meta-data ```r meta <- nettskjema_get_meta(205451) meta ``` ``` ## # Nettskjema metadata for form 205451 ## ## title: Test form for nettskjemar course ## language: en ## opened: 2021-06-01 ## respondents: ALL ## contact: athanasm@uio.no ## codebook: TRUE ## personal_data: FALSE ## sensitive_data: FALSE ## editors: 2 ## no. elements: 6 ``` --- # Accessing other form information ### meta-data ```r meta <- nettskjema_get_meta(205451, as_is = TRUE) meta ``` ``` ## # Nettskjema raw metadata for form 205451 ## ## title: Test form for nettskjemar course ## languageCode: en ## createdDate: 2021-06-01T08:38:10.000+0200 ## respondentGroup: ALL ## editorsContactEmail: athanasm@uio.no ## codebookActivated: TRUE ## collectsPersonalData: FALSE ## sensitivePersonalDataCollected: FALSE ## editors: 2 ## no. elements: 6 ``` --- # Accessing other form information ### meta-data ```r nettskjema_get_meta(205451, as_is = TRUE) %>% nettskjema_write_meta("data/meta_205451_raw.json") nettskjema_get_meta(205451) %>% nettskjema_write_meta("data/meta_205451.json") ``` --- # Things to improve - the linear scale element is not yet supported -- - working within TSD, requires a whole new way of working! -- - pushing data/forms to nettskjema -- - bug fixes that I know of -- - bugs I don't know of yet - report bugs or unexpected behaviour to me [on github](https://github.com/LCBC-UiO/nettskjemar/issues) - if you have some experience in package development, I'm happy for help in documentation, improvements in functionality etc. --- layout: false --- background-image: url("https://drmowinckels.io/about/profile.png") background-position: right bottom background-size: auto 100% class: middle, dark .pull-left[ ## Athanasia Monika Mowinckel [<i class="fa fa-twitter fa-2x" aria-hidden="true"></i> @DrMowinckels](https://twitter.com/DrMowinckels) [<i class="fa fa-github fa-2x" aria-hidden="true"></i> Athanasiamo](https://github.com/Athanasiamo) [<i class="fa fa-globe fa-2x" aria-hidden="true"></i> drmowinckels.io/](https://drmowinckels.io/) - Staff scientist - PhD in cognitive psychology - Software Carpentry Instructor ]