Skip to content

Adding repeat support to redcap_delete #517

Description

@pbchase

I am considering writing support for repeating instruments and events to redcap_delete to meet a local need. REDCap supports the deletion of repeats via the API, but VUMC's implementation raises some questions.

Looking at REDCap 14.1.3, API/record/delete.php, the function delRecords() will iterate over an array of record IDs, but it treats event, instrument, and repeat_instance as scalars. So a deletion of a vector of n repeats of an instrument for one record would require n API calls. You could delete a vector of record IDs for a single repeat of a single instrument, but you would have to build that data structure from the dataset of records and repeats you plan to delete.

It would be nice to ignore the capabilities of the Delete Records API method. I'd prefer to name the repeats I want to delete by record_id, instrument name(s), and repeating instance numbers and let the delete function manage that complexity. This code generates a dataframe of repeats of a form to delete, then transforms them into a data structure that aligns with the capabilities of the REDCap Delete Records API method

library(tidyverse)
library(purrr)

size <- 8
floor <- c(5,6,7,8,9)
repeats_to_delete <- tibble(
  record_id = sample(c(1,2,3,4,5), size = size, replace = T),
  redcap_repeat_instrument = sample(c("plasma_from_edta"), size = size, replace = T),
  redcap_repeat_instance = purrr::map(seq(1, size), ~ sample(floor, size = 1):9)
) |>
  unnest(redcap_repeat_instance) |>
  distinct()

repeats_to_delete

repeats_to_delete |>
  group_by(redcap_repeat_instrument, redcap_repeat_instance) |>
  nest(data = "record_id")

e.g.

> library(tidyverse)
> library(purrr)
> size <- 8
> floor <- c(5,6,7,8,9)
> repeats_to_delete <- tibble(
+   record_id = sample(c(1,2,3,4,5), size = size, replace = T),
+   redcap_repeat_instrument = sample(c("plasma_from_edta"), size = size, replace = T),
+   redcap_repeat_instance = purrr::map(seq(1, size), ~ sample(floor, size = 1):9)
+ ) |>
+   unnest(redcap_repeat_instance) |>
+   distinct()
> repeats_to_delete
# A tibble: 13 × 3
   record_id redcap_repeat_instrument redcap_repeat_instance
       <dbl> <chr>                                     <int>
 1         1 plasma_from_edta                              7
 2         1 plasma_from_edta                              8
 3         1 plasma_from_edta                              9
 4         3 plasma_from_edta                              8
 5         3 plasma_from_edta                              9
 6         4 plasma_from_edta                              9
 7         5 plasma_from_edta                              7
 8         5 plasma_from_edta                              8
 9         5 plasma_from_edta                              9
10         4 plasma_from_edta                              8
11         2 plasma_from_edta                              7
12         2 plasma_from_edta                              8
13         2 plasma_from_edta                              9
> repeats_to_delete |>
+   group_by(redcap_repeat_instrument, redcap_repeat_instance) |>
+   nest(data = "record_id") |>
+   ungroup()
# A tibble: 3 × 3
  redcap_repeat_instrument redcap_repeat_instance data            
  <chr>                                     <int> <list>          
1 plasma_from_edta                              7 <tibble [3 × 1]>
2 plasma_from_edta                              8 <tibble [5 × 1]>
3 plasma_from_edta                              9 <tibble [5 × 1]>

This method works well with multiple instruments as well. I just simplified the above data for readability. It does not address repeating events, but it could with modifications.

With such a data frame, one could call the function like this:

redcap_delete(
  redcap_uri = my_uri,
  token = my_token,
  records_to_delete = repeats_to_delete$record_id,
  instruments_to_delete = repeats_to_delete$redcap_repeat_instrument,
  repeats_to_delete = repeats_to_delete$redcap_repeat_instance,
  ...
)

I'm curious to get feedback on which data transformations to put into redcap_delete's scope and how best to pass the data.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions