% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/answer_as_dataframe.R
\name{answer_as_dataframe}
\alias{answer_as_dataframe}
\title{Make LLM answer as a data frame via structured output}
\usage{
answer_as_dataframe(
  prompt,
  schema,
  min_rows = NULL,
  max_rows = NULL,
  schema_strict = FALSE,
  schema_in_prompt_as = c("example", "schema"),
  type = c("auto", "text-based", "openai", "ollama", "openai_oo", "ollama_oo", "ellmer")
)
}
\arguments{
\item{prompt}{A single string or a \code{\link[=tidyprompt]{tidyprompt()}} object}

\item{schema}{A JSON schema list or an 'ellmer' type definition describing a
single row, an array of rows, or a wrapper object containing a \code{rows} array.}

\item{min_rows}{(optional) Minimum number of rows required in the returned
data frame}

\item{max_rows}{(optional) Maximum number of rows allowed in the returned
data frame}

\item{schema_strict}{If TRUE, the wrapped schema will be strictly enforced.
Passed through to \code{\link[=answer_as_json]{answer_as_json()}}}

\item{schema_in_prompt_as}{Passed through to \code{\link[=answer_as_json]{answer_as_json()}} when using a
text-based JSON path}

\item{type}{Passed through to \code{\link[=answer_as_json]{answer_as_json()}} to control the structured
output backend}
}
\value{
A \code{\link[=tidyprompt]{tidyprompt()}} with an added \code{\link[=prompt_wrap]{prompt_wrap()}} which will ensure
that the LLM response is returned as a data frame.
}
\description{
This function builds on \code{\link[=answer_as_json]{answer_as_json()}} to extract a data frame from an
LLM response using structured output. The supplied \code{schema} should describe a
single row of the desired data frame, or an array of such rows. Internally,
\code{answer_as_dataframe()} standardizes the schema to a JSON object with a
\code{rows} field containing an array of row objects. This shape works well with
both text-based JSON extraction and native structured-output backends,
including 'ellmer', where arrays of objects are converted to data frames.
}
\details{
Prefer supplying an 'ellmer' row schema created with
\code{ellmer::type_object(...)} when possible. This is usually the clearest way to
describe the columns you want, and it maps cleanly to native 'ellmer'
structured output. These 'ellmer' schema definitions can also be used with
non-'ellmer' LLM providers, because 'tidyprompt' converts between 'ellmer'
schema definitions and JSON-schema representations as needed.

\code{answer_as_dataframe()} accepts the following schema shapes:
\itemize{
\item A single row schema, such as \code{ellmer::type_object(...)} or a JSON schema
object whose properties describe the columns of one row.
\item An array-of-rows schema, such as \code{ellmer::type_array(row_schema)} or a JSON
schema with \code{type = "array"} and row objects under \code{items}.
\item A wrapper object whose \strong{only} property is a \code{rows} field containing an
array of row objects (matching the shape produced internally by
\code{answer_as_dataframe()}). Schemas with additional sibling properties
alongside \code{rows} are treated as row schemas, not wrappers.
}

Regardless of which of these forms you supply, \code{answer_as_dataframe()}
normalizes it to a row-oriented structured-output schema before delegating to
\code{\link[=answer_as_json]{answer_as_json()}}.
}
\examples{
# `answer_as_dataframe()` accepts multiple schema shapes.
# Prefer an ellmer row schema when possible, because it is concise and maps
# cleanly to native ellmer structured output.
# These ellmer schema definitions also work with non-ellmer LLM providers,
# because tidyprompt converts between ellmer schemas and JSON schemas for you.

if (requireNamespace("ellmer", quietly = TRUE)) {
  person_row_schema_ellmer <- ellmer::type_object(
    name = ellmer::type_string(),
    age = ellmer::type_integer(),
    city = ellmer::type_string()
  )

  # Also accepted: an array of row objects.
  person_array_schema_ellmer <- ellmer::type_array(person_row_schema_ellmer)
}

# Also accepted: a JSON schema describing one row.
person_row_schema_json <- list(
  type = "object",
  properties = list(
    name = list(type = "string"),
    age = list(type = "integer"),
    city = list(type = "string")
  ),
  required = c("name", "age", "city"),
  additionalProperties = FALSE
)

# Also accepted: a wrapper object with a `rows` array.
person_wrapper_schema_json <- list(
  type = "object",
  properties = list(
    rows = list(
      type = "array",
      items = person_row_schema_json
    )
  ),
  required = "rows",
  additionalProperties = FALSE
)

\dontrun{
  prompt <- paste(
    "Extract the people in the following notes as a table:",
    "Alice (32, Berlin), Bob (28, Utrecht)."
  )

  # Preferred: ellmer row schema.
  # This works both with ellmer-backed providers and with regular tidyprompt
  # providers, because tidyprompt converts the schema when needed.
  if (requireNamespace("ellmer", quietly = TRUE)) {
    prompt |>
      answer_as_dataframe(person_row_schema_ellmer) |>
      send_prompt()
    #    name age    city
    # 1 Alice  32  Berlin
    # 2   Bob  28 Utrecht

    # Also works: ellmer array-of-rows schema.
    prompt |>
      answer_as_dataframe(person_array_schema_ellmer) |>
      send_prompt()
  }

  # Also works: JSON schema for one row.
  prompt |>
    answer_as_dataframe(person_row_schema_json, type = "text-based") |>
    send_prompt()

  # Also works: JSON wrapper schema with a `rows` array.
  prompt |>
    answer_as_dataframe(person_wrapper_schema_json, type = "text-based") |>
    send_prompt()
}
}
\seealso{
Other pre_built_prompt_wraps: 
\code{\link{add_image}()},
\code{\link{add_text}()},
\code{\link{answer_as_boolean}()},
\code{\link{answer_as_category}()},
\code{\link{answer_as_integer}()},
\code{\link{answer_as_json}()},
\code{\link{answer_as_list}()},
\code{\link{answer_as_multi_category}()},
\code{\link{answer_as_named_list}()},
\code{\link{answer_as_numeric}()},
\code{\link{answer_as_regex_match}()},
\code{\link{answer_as_text}()},
\code{\link{answer_by_chain_of_thought}()},
\code{\link{answer_by_react}()},
\code{\link{answer_using_r}()},
\code{\link{answer_using_sql}()},
\code{\link{answer_using_tools}()},
\code{\link{prompt_wrap}()},
\code{\link{quit_if}()},
\code{\link{set_system_prompt}()}

Other answer_as_prompt_wraps: 
\code{\link{answer_as_boolean}()},
\code{\link{answer_as_category}()},
\code{\link{answer_as_integer}()},
\code{\link{answer_as_json}()},
\code{\link{answer_as_list}()},
\code{\link{answer_as_multi_category}()},
\code{\link{answer_as_named_list}()},
\code{\link{answer_as_numeric}()},
\code{\link{answer_as_regex_match}()},
\code{\link{answer_as_text}()}
}
\concept{answer_as_prompt_wraps}
\concept{pre_built_prompt_wraps}
