| Title: | Data Extraction for Meta-Analysis with Large Language Models |
|---|---|
| Description: | Use Large Language Models (LLMs) to assist with data extraction for meta-analysis. This package incorporates three modular Shiny apps to implement a human-in-the-loop framework. (1) a manual extraction interface for abstracts, (2) refining prompt engineering and model selection, and (3) validation of LLM-generated outputs. These apps enable researchers to iteratively collaborate with LLMs, with each abstract undergoing double data extraction—once manually by a human researcher and once independently by an LLM-assisted process—to emulate the double extraction process recommended by international standards. Notably, the package runs fully on local machines, with no need for API setup or external data transfer, maximising data privacy and accessibility. Robust logging features further enhance transparency and reproducibility by recording all prompt iterations and outputs. |
| Authors: | Danyang Dai [aut, cre, cph] (ORCID: <https://orcid.org/0009-0006-3984-291X>), Emi Tanaka [aut] (ORCID: <https://orcid.org/0000-0002-1455-259X>), Jason Pole [ths] (ORCID: <https://orcid.org/0000-0002-0413-5434>) |
| Maintainer: | Danyang Dai <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-07-05 08:34:36 UTC |
| Source: | https://github.com/DanyangDai/metaextractoR |
This dataset includes sample abstracts downloaded from one of my Covidence project. Pre-processing was done by running the clean_name function from janitor package.
abstracts app_2 app_3 testing_stage_0_data training_stage_0_dataabstracts app_2 app_3 testing_stage_0_data training_stage_0_data
A data frame with 20 rows and 16 variables:
Title of the manuscript
Authors
The column that contains all abstracts
Year of the publication
Month of the publication
Journal's name
Volume number
Issue number
Page number
Accession number
doi number
Reference
Covidence number
Study
Notes
Tags
An object of class spec_tbl_df (inherits from tbl_df, tbl, data.frame) with 10 rows and 15 columns.
An object of class spec_tbl_df (inherits from tbl_df, tbl, data.frame) with 40 rows and 16 columns.
An object of class spec_tbl_df (inherits from tbl_df, tbl, data.frame) with 40 rows and 16 columns.
An object of class spec_tbl_df (inherits from tbl_df, tbl, data.frame) with 10 rows and 16 columns.
Created for demonstration purposes
Pre-processing functions and saving intermediate data
add_predefined_vars(data, list_vars)add_predefined_vars(data, list_vars)
data |
a csv file contains abstract information. This could be the csv file downloaded from covidence |
list_vars |
a vector of data elements you want to extract. i.e. c("no_participants,"no_female","..") |
new dataset with additional empty columns
add_predefined_vars(abstracts, c("no_participants", "no_aki", "age_mean", "age_sd"))add_predefined_vars(abstracts, c("no_participants", "no_aki", "age_mean", "age_sd"))
This function launches a Shiny app that displays each abstract alongside the data elements you want to extract. The app provides an interactive interface for manually entering this information, helping to fill out the _manual column generated by the 'add_predefined_vars()' function in the training set.
glance_manual_app()glance_manual_app()
Runs a shiny app.
if (interactive()) { glance_manual_app() }if (interactive()) { glance_manual_app() }
This Shiny app allows you to manually review the results generated by the 'process_with_ollama()' function. By uploading a testing dataset with LLM-extracted values, you can systematically check and validate each field filled out by the model.
manual_validation_app()manual_validation_app()
Runs a shiny app.
if (interactive()) { manual_validation_app() }if (interactive()) { manual_validation_app() }
A function that batch process data extraction from text.
process_with_ollama( input, model = "llama3.1:8b", type_abstract, i, abstract_col )process_with_ollama( input, model = "llama3.1:8b", type_abstract, i, abstract_col )
input |
A data frame contains abstracts and variables we want to extract. If you are not sure how the data should look like, please see the example dataset abstract. This data should be the testing data saved using the 'save_training_data()' function. |
model |
Large Language Model name you want to use i.e. "llama3.1:8b". If you are not sure what LLMs have been installed locally, please use the function: ellmer:::ollama_models() to find out what LLMs are available. |
type_abstract |
is created using the type_object function from the ellmer package. Objects represent a collection of named values and are created with type_object(). Objects can contain any number of scalars, arrays, and other objects. They are similar to named lists in R. If still not sure, please look up the documentation of ellmer::type_object(). |
i |
number of abstracts you want to process at once. |
abstract_col |
column name for the column contains abstract. |
Returns a data.frame with results and time.
library(ellmer) type_abstract <- type_object("Some key information from abstract.", no_patients_llm = type_integer("Find the total number of patients included in this study.", required = FALSE), no_AKI_llm = type_integer("Number of Acute Kidney Injury (AKI) patients included in this study.", required = FALSE), per_AKI_llm = type_number("Percentage of Acute Kidney Injury ", required = FALSE), ICU_llm = type_boolean("Included only Intensive Care Unit (ICU) patients.", required = FALSE), start_date = type_string("The starting date of the study written in YYYY-MM-DD format", required = FALSE), end_date = type_string("The end date of the study written in YYYY-MM-DD format", required = FALSE), age_mean_llm = type_number("Find the average age of the study cohort", required = FALSE), age_median_llm = type_number("Find the median age of the study cohort", required = FALSE) ) ## Not run: process_with_ollama(abstracts, type_abstract = type_abstract, i = 1, abstract_col = "Abstract") ## End(Not run)library(ellmer) type_abstract <- type_object("Some key information from abstract.", no_patients_llm = type_integer("Find the total number of patients included in this study.", required = FALSE), no_AKI_llm = type_integer("Number of Acute Kidney Injury (AKI) patients included in this study.", required = FALSE), per_AKI_llm = type_number("Percentage of Acute Kidney Injury ", required = FALSE), ICU_llm = type_boolean("Included only Intensive Care Unit (ICU) patients.", required = FALSE), start_date = type_string("The starting date of the study written in YYYY-MM-DD format", required = FALSE), end_date = type_string("The end date of the study written in YYYY-MM-DD format", required = FALSE), age_mean_llm = type_number("Find the average age of the study cohort", required = FALSE), age_median_llm = type_number("Find the median age of the study cohort", required = FALSE) ) ## Not run: process_with_ollama(abstracts, type_abstract = type_abstract, i = 1, abstract_col = "Abstract") ## End(Not run)
This Shiny app is designed for model testing and prompt engineering. It uses the training set—with manually extracted values from 'glance_manual_app()' —as the reference for training and evaluation. When run, the function automatically creates a log_files folder in your current working directory. After you exit the prompt_engineering_app, a CSV file is saved in this folder, containing details of each prompt tested, results, runtime, model type, and accuracy. This log supports model selection, documentation, and reproducibility. The chosen model and prompt can be used for the 'process_with_ollama()' function.
prompt_engineering_app()prompt_engineering_app()
Runs a shiny app.
if (interactive()) { prompt_engineering_app() }if (interactive()) { prompt_engineering_app() }
This function will save the testing abstract data with empty columns to the processed data folder. This csv file will be used in the shinyapp 2 The data will be stored in metaextroctor_process_data
save_testing_data(testing_abs)save_testing_data(testing_abs)
testing_abs |
training abstracts including the variables you want to extract. |
a csv file saved in the metaextroctor_process_data file named training_stage_0_data.csv
This function will save the training abstract data with empty columns to the processed data folder. This csv file will be used in the shinyapp 1 The data will be stored in metaextroctor_process_data
save_training_data(training_abs)save_training_data(training_abs)
training_abs |
training abstracts including the variables you want to extract. |
a csv file saved in the metaextroctor_process_data file named training_stage_0_data.csv
This function separates the abstracts into training and testing sets.
separate_training(data, percentage = 0.1)separate_training(data, percentage = 0.1)
data |
The csv file contains abstracts with |
percentage |
percentage of separation training sets. If percentage set to be 0.1, 10% of the data will be the training set and 90% of the data will be testing set. |
A list with two the train and test data.frames.
separate_training(abstracts, percentage = 0.4)separate_training(abstracts, percentage = 0.4)