Skip to content

Commit

Permalink
Merge pull request #3 from UBESP-DCTV/2-update-period
Browse files Browse the repository at this point in the history
Update period
  • Loading branch information
CorradoLanera committed Aug 22, 2024
2 parents 16f693a + 1391a57 commit f47696c
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 70 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: redcap.gpt
Title: What the Package Does (One Line, Title Case)
Version: 0.1.1
Version: 0.1.1.9000
Authors@R: c(
person("Corrado", "Lanera", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0002-0520-7428")),
Expand Down
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export(get_redcap_pid)
export(get_redcap_token)
export(get_redcap_uri)
export(gpt_to_tibble)
export(parse_checkbox)
export(parse_gpt_fctr)
export(parse_sensazione)
export(query_gpt_on_redcap_instrument)
importFrom(rlang,"!!")
importFrom(rlang,":=")
Expand Down
9 changes: 7 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# redcap.gpt (development version)

* allow `query_gpt_on_redcap_instrument` to process the whole db setting `query_all_records` to `TRUE`.
* change `parse_sensazione` to a more general `parse_checkbox`.

# redcap.gpt 0.1.1

* Added support of `targets` and `tarchetypes`
* Fix levels name for the trend question (fix issue #1)
* Added support of `targets` and `tarchetypes`.
* Fix levels name for the trend question (fix issue #1).

# redcap.gpt 0.1.0

Expand Down
12 changes: 6 additions & 6 deletions R/parse_answer.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#' Parser for `answer` columns
#' Parser for checkboxes
#'
#' Converts GPT answers yes/no to logical.
#'
Expand All @@ -8,11 +8,11 @@
#' @export
#'
#' @examples
#' parse_sensazione("si")
#' parse_sensazione("no")
#' parse_sensazione("NA")
#' parse_sensazione("N/A")
parse_sensazione <- function(x) {
#' parse_checkbox("si")
#' parse_checkbox("no")
#' parse_checkbox("NA")
#' parse_checkbox("N/A")
parse_checkbox <- function(x) {
res <- stringi::stri_enc_toascii(stringr::str_to_lower(x)) == "si"
tidyr::replace_na(res, FALSE) |>
as.integer()
Expand Down
31 changes: 23 additions & 8 deletions R/query_composers.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ compose_usr_task <- function() {

compose_usr_instructions <- function() {
"Dal testo fornito dal soggetto, riportato qui di seguito tra la coppia di delimitatori `#####`, estrai le seguenti informazioni:
- [sensazione_calmo]: il soggetto sembra calmo/tranquillo/sereno? - {si/no}
- [sensazione_irritato]: il soggetto sembra irritato/infastidito? - {si/no}
- [sensazione_ansioso]: il soggetto sembra ansioso/preoccupato/nervoso? - {si/no}
- [sensazione_ottimista]: il soggetto sembra ottimista/positivo verso il recupero? - {si/no}
- [sensazione_demotivato]: il soggetto sembra demotivato/negativo verso il recupero? - {si/no}
- [sensazione_stanco]: il soggetto sembra stanco/esaurito fisicamente o mentalmente? - {si/no}
- [momento]: in quali momenti della giornata sono collocate le sesazioni descritte? - {mattina (05-11) / pomeriggio (11-17) / sera (17-23) / notte (23-05)}
- [sensazione_calmo]: basandosi sul tono/stile e su quanto esplicitamente scritto, il soggetto sembra calmo/tranquillo/sereno? - {si/no}
- [sensazione_irritato]: basandosi sul tono/stile e su quanto esplicitamente scritto, il soggetto sembra irritato/infastidito? - {si/no}
- [sensazione_ansioso]: basandosi sul tono/stile e su quanto esplicitamente scritto, il soggetto sembra ansioso/preoccupato/nervoso? - {si/no}
- [sensazione_ottimista]: basandosi sul tono/stile e su quanto esplicitamente scritto, il soggetto sembra ottimista/positivo verso il recupero? - {si/no}
- [sensazione_demotivato]: basandosi sul tono/stile e su quanto esplicitamente scritto, il soggetto sembra demotivato/negativo verso il recupero? - {si/no}
- [sensazione_stanco]: basandosi sul tono/stile e su quanto esplicitamente scritto, il soggetto sembra stanco/esaurito fisicamente o mentalmente? - {si/no}
- [momento_mattina]: ci sono sensazioni che nella descrizione sono state collocate (esplicitamente) al mattino? - {si/no}
- [momento_pomeriggio]: ci sono sensazioni che nella descrizione sono state collocate (esplicitamente) al pomeriggio? - {si/no}
- [momento_sera]: ci sono sensazioni che nella descrizione sono state collocate (esplicitamente) alla sera? - {si/no}
- [momento_notte]: ci sono sensazioni che nella descrizione sono state collocate (esplicitamente) nella notte? - {si/no}
- [andamento]: come pare stia procedendo il recupero? - {peggiore/migliore/costante/altalenante}
- [impatto]: che impatto sulle attività si manifesta? - {nessuno (attività regolari) / leggero (disagio nel condurre le attività) / moderato (impedimenti nel condurre le attività) / grave (limitazioni nel condurre le attività) / critico (impossibilità di condurre le attività)}
"
Expand Down Expand Up @@ -60,7 +63,19 @@ compose_usr_example <- function() {
"risposta": <rispsota>,
"motivazione": <motivazione per la risposta data>
},
momento = {
momento_mattina = {
"risposta": <rispsota>,
"motivazione": <motivazione per la risposta data>
},
momento_pomeriggio = {
"risposta": <rispsota>,
"motivazione": <motivazione per la risposta data>
},
momento_sera = {
"risposta": <rispsota>,
"motivazione": <motivazione per la risposta data>
},
momento_notte = {
"risposta": <rispsota>,
"motivazione": <motivazione per la risposta data>
},
Expand Down
80 changes: 40 additions & 40 deletions R/query_gpt_on_redcap_instrument.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@
#' @param instrument (chr) The REDCap instrument of the form to query.
#' @param model (chr, default: "gpt-4o-mini") The GPT model to use.
#' @param seed (int, default: 1234) The seed for the GPT model.
#' @param query_on_all_records (lgl, default: FALSE) If TRUE, the
#' content of the "text_processed_record" variable (which mark if a
#' record has already been processed) will be ignored. If FALSE
#' (default) only records not marked as already processed will be
#' considered.
#'
#' @return (tbl_df) The REDCap DB with GPT responses parsed.
#' @export
query_gpt_on_redcap_instrument <- function(
db,
instrument = c("note_fup", "comments_fup", "details_fup"),
model = "gpt-4o-mini",
seed = 1234
seed = 1234,
query_on_all_records = FALSE
) {
instrument <- match.arg(instrument)
checkmate::assert_subset(instrument, names(db))
stopifnot(
sum(stringr::str_detect(
names(db), stringr::str_glue("{instrument}_text")
)) == 19
)) == 25
)

db_to_query <- db |>
Expand All @@ -30,7 +36,7 @@ query_gpt_on_redcap_instrument <- function(
) |>
dplyr::filter(
!is.na(.data[[instrument]]),
!.data[[
query_on_all_records | !.data[[
stringr::str_c(instrument, "_text_processed_record___1")
]]
) |>
Expand Down Expand Up @@ -89,8 +95,15 @@ query_gpt_on_redcap_instrument <- function(
stanco_response <- stringr::str_glue("{instrument}_text_feeling___6")
stanco_motivation <- stringr::str_glue("{instrument}_text_feeling_6_motivation")

momento_response <- stringr::str_glue("{instrument}_text_daytime")
momento_motivation <- stringr::str_glue("{instrument}_text_daytime_motivation")
mattina_response <- stringr::str_glue("{instrument}_text_daytime___1")
mattina_motivation <- stringr::str_glue("{instrument}_text_daytime_1_motivation")
pomeriggio_response <- stringr::str_glue("{instrument}_text_daytime___2")
pomeriggio_motivation <- stringr::str_glue("{instrument}_text_daytime_2_motivation")
sera_response <- stringr::str_glue("{instrument}_text_daytime___3")
sera_motivation <- stringr::str_glue("{instrument}_text_daytime_3_motivation")
notte_response <- stringr::str_glue("{instrument}_text_daytime___4")
notte_motivation <- stringr::str_glue("{instrument}_text_daytime_4_motivation")

andamento_response <- stringr::str_glue("{instrument}_text_trend")
andamento_motivation <- stringr::str_glue("{instrument}_text_trend_motivation")
impatto_response <- stringr::str_glue("{instrument}_text_impact")
Expand All @@ -104,11 +117,11 @@ query_gpt_on_redcap_instrument <- function(
),
dplyr::across(
dplyr::matches("^sensazione_.*_risposta"),
parse_sensazione
parse_checkbox
),
momento_risposta = parse_gpt_fctr(
from_str = .data[["momento_risposta"]],
to_fct = .data[[momento_response]]
dplyr::across(
dplyr::matches("^momento_.*_risposta"),
parse_checkbox
),
andamento_risposta = parse_gpt_fctr(
from_str = .data[["andamento_risposta"]],
Expand All @@ -132,8 +145,16 @@ query_gpt_on_redcap_instrument <- function(
!!demotivato_motivation := .data[["sensazione_demotivato_motivazione"]],
!!stanco_response := .data[["sensazione_stanco_risposta"]],
!!stanco_motivation := .data[["sensazione_stanco_motivazione"]],
!!momento_response := .data[["momento_risposta"]],
!!momento_motivation := .data[["momento_motivazione"]],

!!mattina_response := .data[["momento_mattina_risposta"]],
!!mattina_motivation := .data[["momento_mattina_motivazione"]],
!!pomeriggio_response := .data[["momento_pomeriggio_risposta"]],
!!pomeriggio_motivation := .data[["momento_pomeriggio_motivazione"]],
!!sera_response := .data[["momento_sera_risposta"]],
!!sera_motivation := .data[["momento_sera_motivazione"]],
!!notte_response := .data[["momento_notte_risposta"]],
!!notte_motivation := .data[["momento_notte_motivazione"]],

!!andamento_response := .data[["andamento_risposta"]],
!!andamento_motivation := .data[["andamento_motivazione"]],
!!impatto_response := .data[["impatto_risposta"]],
Expand All @@ -152,8 +173,14 @@ query_gpt_on_redcap_instrument <- function(
"sensazione_demotivato_motivazione",
"sensazione_stanco_risposta",
"sensazione_stanco_motivazione",
"momento_risposta",
"momento_motivazione",
"momento_mattina_risposta",
"momento_mattina_motivazione",
"momento_pomeriggio_risposta",
"momento_pomeriggio_motivazione",
"momento_sera_risposta",
"momento_sera_motivazione",
"momento_notte_risposta",
"momento_notte_motivazione",
"andamento_risposta",
"andamento_motivazione",
"impatto_risposta",
Expand All @@ -169,30 +196,3 @@ query_gpt_on_redcap_instrument <- function(
dplyr::across(dplyr::where(is.logical), \(x) as.integer(x))
)
}


var_to_map <- function(x) {
c(
feeling___1 = "calmo",
feeling___2 = "irritato",
feeling___3 = "ansioso",
feeling___4 = "ottimista",
feeling___5 = "demotivato",
daytime = "momento",
trend = "andamento",
impact = "impatto"
)[x]
}

map_to_var <- function(x) {
c(
calmo = "feeling___1",
irritato = "feeling___2",
ansioso = "feeling___3",
ottimista = "feeling___4",
demotivato = "feeling___5",
momento = "daytime",
andamento = "trend",
impatto = "impact"
)[x]
}
2 changes: 1 addition & 1 deletion analyses/write.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fup_143060 <- fetch_form("followup_postoperatorio_14_30_60_giorno_po")
fup_90 <- fetch_form("visita_followup_postoperatorio_90_giorno_po")

note_fup_to_be_pushed <- fup_143060 |>
query_gpt_on_redcap_instrument("note_fup")
query_gpt_on_redcap_instrument("note_fup")
comments_fup_to_be_pushed <- fup_143060 |>
query_gpt_on_redcap_instrument("comments_fup")
details_fup_to_be_pushed <- fup_90 |>
Expand Down
16 changes: 8 additions & 8 deletions man/parse_sensazione.Rd → man/parse_checkbox.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion man/query_gpt_on_redcap_instrument.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/testthat/test-parse_answer.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
test_that("parse_sensazione works", {
test_that("parse_checkbox works", {
# evaluate
res <- parse_sensazione(c("si", "no", "forse", NA))
res <- parse_checkbox(c("si", "no", "forse", NA))

# test
expect_equal(res, c(1, 0, 0, 0))
Expand Down

0 comments on commit f47696c

Please sign in to comment.