Skip to content

R SDK

The R SDK gives R the ten functions, from tt_decide() to tt_annotate(); each takes your texts and gives back a plain R vector with one answer per text, such as TRUE or FALSE from decide, or NA when it is not sure.

refund.R
library(thinkthen)
is_refund <- tt_decide("Please refund my order.",
question = "Does the customer request a refund?")
print(is_refund)

Output

[1] TRUE

TRUE means yes: the message asks for a refund.

Install it (R 4.2.0 or later):

Terminal window
install.packages("thinkthen", repos = c(
"https://botassembly.r-universe.dev", "https://cloud.r-project.org"))

The client uses the key from the Quickstart.

Set a low bar and a high bar with threshold = c(0.2, 0.8). Between them, decide is not sure, and the answer is NA. if (NA) stops with an error, so not sure never passes for no. When ThinkThen can't judge a text, such as a blank one, the call raises a thinkthen_failed_rows error instead of answering.

unsure.R
library(thinkthen)
question <- "Does the customer request a refund?"
is_refund <- tt_decide("I was charged twice for one invoice.",
question = question,
threshold = c(0.2, 0.8))
print(is_refund)
failure <- tryCatch(tt_decide("", question = question),
thinkthen_failed_rows = identity)
print(failure$code)

Output

[1] NA
[1] "record.empty"

A double charge might be a refund request, or might not, so the answer is NA: send it to a person. The blank text can't be judged, so the call raises, and the error's code is record.empty.

Test is.na() before you branch on an answer. The error is raised only after every other text is judged; its failed_rows lists the texts that failed, and rows holds every outcome already paid for. Every ThinkThen error inherits thinkthen_error and carries a code; Troubleshooting lists each one.

Each function takes the texts first, as a character vector, a list or a data frame, and answers each text in input order. Name question = so a swapped call can't ask the wrong question. Every program reads the same support-inbox messages as the function pages.

Yes or no about each text
decide.R
library(thinkthen)
is_refund <- tt_decide("Please refund my order.",
question = "Does the customer request a refund?")
print(is_refund)

Output

[1] TRUE

Yes: the message asks for a refund. tt_decide() also takes threshold, one bar or a low and a high bar, and yes_means and no_means, which say in words what each answer means. decide shows every option.

The one choice that fits
choose.R
library(thinkthen)
topic <- tt_choose("Please refund my order.",
question = "What is the message about?",
choices = c("billing", "shipping", "other"))
print(topic)

Output

[1] "billing"

A refund is about billing. The answer is one of your choices, or NA when not sure. descriptions says what each choice means, and threshold sets the bar. choose shows every option.

Only the texts that answer yes
filter.R
library(thinkthen)
messages <- c("Please refund my order.",
"Where is my parcel?",
"I was charged twice for one invoice.")
refund_requests <- tt_filter(messages,
question = "Does the customer request a refund?")
print(refund_requests)

Output

[1] "Please refund my order."
[2] "I was charged twice for one invoice."

The parcel question is left out. tt_filter() gives back your own texts, in the form you passed, and leaves out the ones it is not sure about. If any text fails, it raises thinkthen_failed_rows after judging the rest, and the error's kept holds the kept texts. tt_keep() gives the same answer as TRUE, FALSE or NA for each text, for dplyr::filter(). filter shows every option.

Every label that fits
tag.R
library(thinkthen)
topics <- tt_tag("I was charged twice and my parcel is late again.",
question = "Which topics appear?",
labels = c("billing", "shipping"))[[1]]
print(topics)

Output

[1] "billing"  "shipping"

The message is about both billing and shipping. tt_tag() gives a list with one character vector per text, so [[1]] takes the first. tag shows every option.

A number from 0 to 1 on your scale
score.R
library(thinkthen)
urgency <- tt_score("Please refund my order.",
question = "How urgent is the request?",
levels = c("routine", "urgent"))
print(urgency)

Output

[1] 0.05

The levels run lowest first, so a plain refund request scores near routine. score shows every option.

Every text, highest first
rank.R
library(thinkthen)
messages <- c("Please refund my order.",
"Where is my parcel?",
"I was charged twice for one invoice.")
urgency_rank <- tt_rank(messages,
question = "How urgent is the request?",
levels = c("routine", "urgent"))
print(urgency_rank)

Output

[1] 3 2 1

The double charge is the most urgent. Each text gets its rank, starting at 1, in input order, so messages[order(urgency_rank)] puts the most urgent first. With top = 2, ranks past the first two are NA. rank shows every option.

The line that answers the question
find.R
library(thinkthen)
action <- tt_find("Morgan works for Example Group.\nPlease refund my order.",
question = "Which line states the requested action?")
print(action$text)

Output

[1] "Please refund my order."

The second line states the action. The answer has $text, $start and $end, counted in characters from 1 with the end included, so substr(text, action$start, action$end) gives the line. $text is NA when no line answers. find shows every option.

Each name in the text and its kind
recognize.R
library(thinkthen)
mentions <- tt_recognize("Morgan works for Example Group.",
kinds = c("person", "organization"))[[1]]
print(data.frame(text = mentions$text, kind = mentions$kind))

Output

           text         kind
1        Morgan       person
2 Example Group organization

tt_recognize() gives a list with the names found in each text. Each name has $text, $kind, $start, $end and $probability. recognize shows every option.

Names linked by the relations you allow
relate.R
library(thinkthen)
employers <- tt_relate(
"Morgan works for Example Group.\nPlease refund my order.",
rules = tt_rule("person", "organization", "works_for")
)[[1]]
print(data.frame(source = employers$source$text,
relation = employers$relation,
target = employers$target$text))

Output

  source  relation        target
1 Morgan works_for Example Group

tt_rule() names the kind of name at each end and the relation between them; rules takes one rule or a list() of them. Relate finds its own names, so it needs no recognize call first. relate shows every option.

Several questions for each text
annotate.R
library(thinkthen)
messages <- c("Please refund my order.",
"Where is my parcel?",
"I was charged twice for one invoice.")
inbox_form <- tt_toolbox(list(
"refund" = tt_decide_question("Does the customer request a refund?"),
"topic" = tt_choose_question("What is the message about?",
choices = c("billing", "shipping", "other")),
"urgency" = tt_score_question("How urgent is the request?",
levels = c("routine", "urgent"))
))
triage <- tt_annotate(messages, inbox_form)
print(triage)

Output

# A tibble: 3 × 3
  refund topic    urgency
  <lgl>  <chr>      <dbl>
1 TRUE   billing     0.05
2 FALSE  shipping    0.14
3 TRUE   billing     0.45

tt_annotate() gives a tibble with one column per question, each of its own type, and NA where a question is not sure. annotate shows every option.

field = "/text" judges the text column of a data frame, or the text field of each list. Each function has a _rows twin, such as tt_decide_rows(), that gives every outcome with its status and probability, and tt_bind() adds those to a copy of your data frame. tt_client() makes your own client, and Esc or Ctrl-C cancels a running call. The R API reference lists every function and argument.