--- title: "Describe your analysis in words" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Describe your analysis in words} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` `mv_ask()` writes a complete R script from a plain-language description of the analysis you want. You check the script, then run it or save it. The script is ordinary, commented R code, so you can rerun it later, share it with a colleague, or learn R from it. ```{r setup} library(mirtverse) ``` ## A first request Here is a small data set: twelve 0/1 items, a gender column and a student ID. ```{r} set.seed(1) a <- matrix(rlnorm(12, 0.2, 0.25)); d <- matrix(rnorm(12)) mydata <- data.frame(student_id = 1:800, simdata(a, d, 800, itemtype = "2PL"), gender = rep(c("F", "M"), 400)) names(mydata)[2:13] <- paste0("Q", 1:12) scr <- mv_ask("Fit a 2PL, check DIF by gender and make a report", data = mydata, provider = "none") scr ``` The printout shows how the request was understood (the *plan*), any assumptions mirtverse made, and the script. Nothing has been run yet. * `run_script(scr)` runs it and returns the objects it created (`mod`, `dif_res`, ...). `run_script(scr, check = TRUE)` first runs the whole script on simulated data with the same structure as yours, so errors show up before your data are touched. * `save_script(scr, "analysis.R", open = TRUE)` writes it to a file and opens it in RStudio or Positron. ## Changing the script Pass the script back with the change you want; the rest of the plan is kept. ```{r} scr <- mv_ask(scr, "use a 3PL instead and save EAP scores to scores.csv") scr$plan ``` ## Who understands the request? By default a built-in keyword parser reads the request. It works offline, needs nothing installed, and when something is unclear (for example, "check DIF" in a data set with several possible grouping columns) it asks a short question in the console. For freer wording, connect an AI model once with `mv_ask_setup()`: ```{r, eval = FALSE} mv_ask_setup("claude") # Anthropic Claude, your own API key mv_ask_setup("openai") # OpenAI GPT, your own API key mv_ask_setup("ollama", model = "qwen2.5") # a free model on your own computer ``` The setup asks for the key with a masked prompt, sends one tiny test request, and offers to save the settings in your `.Renviron` file or the system keychain, so you only do it once. Keys are never written into scripts or reports. Ollama () runs the model on your own machine, so nothing leaves it; it needs about 8 GB of memory for a mid-size model. Whatever the model, it only fills in the plan. The R code always comes from mirtverse's tested templates, and the plan is checked against your data before any code is written (do the columns exist, does the group have at least two levels, is a 2PL being asked of items with more than two categories). ## What is sent to the AI model Never individual responses. The model receives your request and a summary of each column: its type, number of distinct values, range, share missing, its guessed role, and the category labels of likely grouping columns. This is what `profile_data()` shows: ```{r} profile_data(mydata) ``` To see exactly what would be sent, use `dry_run = TRUE`. With `anonymize = TRUE` the column names are replaced by V1, V2, ... (also inside your request) and category labels are dropped; mirtverse maps the names back locally. ```{r} mv_ask("check DIF by gender", data = mydata, anonymize = TRUE, dry_run = TRUE) ``` ## Writing a plan by hand The plan is an ordinary R object, so you can also skip the request and write it yourself: ```{r} pl <- mv_plan(items = "Q1:Q10", model = "Rasch", missing = 9, steps = c("describe", "fitcheck", "scores", "report")) mv_ask(data = mydata, plan = pl) ```