Turn a tally of emoji into text the other verbs can read
Source:R/emoji-counts.R
emoji_from_counts.Rdemoji_from_counts() takes data that records emoji as counts (one row per
item and emoji, with how many times it was used) and writes out, for each
item, a text holding each emoji that many times. Every verb in the package
then reads it like any other text column, so reaction data can be scored,
counted, profiled over time and turned into a document-by-emoji matrix.
Usage
emoji_from_counts(data, emoji, n, id = NULL, unknown = c("error", "drop"))Arguments
- data
A data frame with one row per (item, emoji) count.
- emoji
The unquoted column holding the emoji (see Details).
- n
The unquoted column holding the counts.
- id
Optional unquoted column identifying the item each count belongs to. Without it the whole table is one document.
- unknown
What to do with a value of
emojithat resolves to no emoji:"error"(the default) stops and names it, since a silent drop changes answers;"drop"removes its rows and warns once, naming each such value with the total count it carried. Real tallies need it: the OASST2 one bundled as oasst_reactions records interface actions ("_skip_reply") beside the emoji.
Value
A tibble with one row per item, in order of first appearance: the
id column (under its own name) when given, and text, the emoji
written out.
Details
The contract is an identity. The text written for a tally gives exactly
the counts, scores and matrix the original text would have given:
emoji_frequency(), emoji_sentiment(), emoji_emotion() and
emoji_dfm() cannot tell the two apart. The emoji are separated by single
spaces, so two tallied glyphs cannot fuse into a third (a tone and a hand
into a toned hand, two regional indicators into a flag), and nothing else
is added. Verbs that measure the text around emoji, such as
emoji_position(), emoji_context() and emoji_ratio(), are measuring
those spaces, and have nothing to say about a tally.
The emoji column can hold glyphs in any spelling, the names of GitHub's
eight reactions ("+1", "-1", "laugh", "hooray", "confused",
"heart", "rocket", "eyes", as its REST API returns them, or
"THUMBS_UP", "THUMBS_DOWN" and the rest, as its GraphQL API does, in
any case), shortcodes with or without their colons, Slack's names (its
own set, from emojibase's iamcal preset, read here and nowhere else) and
its toned names ("thumbsup::skin-tone-2", tone 2 light to 6 dark), or
Unicode names.
Every glyph is written in its canonical spelling, so a bare U+2764 in the
tally is read by the default presentation. A value that resolves to no
emoji is an error naming it, rather than a silent zero, unless
unknown = "drop"; a Slack tone on an emoji that takes none resolves to
no emoji.
n must be a whole number of at least 0. A fractional count, such as a
survey weight or an average, is refused rather than rounded: a text cannot hold
2.5 emoji, and truncating it would change the answer without saying so.
An item whose counts are all zero keeps its row, with an empty text, so it
still counts as a document wherever the number of documents matters (the
inverse document frequency of emoji_dfm(), for one). So does an item
whose every row unknown = "drop" removed.
One item's text is one R string, which holds at most 2,147,483,647 bytes. A tally that would write more for one item, about 430 million thumbs-up, is refused before anything is built, with the item and the size named. A count that size is a weight over a corpus rather than a tally of one item's reactions, and a text cannot carry a weight; score the glyph once and multiply instead.
What a reaction count measures. A tally records which buttons were pressed, and the set of buttons is the platform's: GitHub offers eight, so "nobody reacted with a skull" says nothing about whether anyone thought it. A study of Telegram reactions found them unreliable indicators of emotional resonance, for that reason among others. The scores this makes possible are scores of what the platform let people say.
See also
emoji_dfm(), emoji_sentiment() and emoji_frequency() for what
to do with the result.
Examples
reactions <- data.frame(
pr = c(101, 101, 102),
reaction = c("+1", "rocket", "-1"),
count = c(3, 1, 2)
)
txt <- emoji_from_counts(reactions, reaction, count, id = pr)
txt
#> # A tibble: 2 × 2
#> pr text
#> <dbl> <chr>
#> 1 101 👍 👍 👍 🚀
#> 2 102 👎 👎
emoji_sentiment(txt, text)
#> # A tibble: 2 × 5
#> pr text .emoji_n .emoji_n_scored .emoji_sentiment
#> <dbl> <chr> <int> <int> <dbl>
#> 1 101 👍 👍 👍 🚀 4 4 0.523
#> 2 102 👎 👎 2 2 -0.190
# GraphQL names and Slack's tones resolve too
emoji_from_counts(data.frame(r = c("THUMBS_UP", "thumbsup::skin-tone-4"),
n = 1), r, n)
#> # A tibble: 1 × 1
#> text
#> <chr>
#> 1 👍 👍🏽
# a real tally, with the interface's skip actions set aside
oasst <- emoji_from_counts(oasst_reactions, reaction, n, id = message_id,
unknown = "drop")
#> Warning: Dropped 4 values of `emoji` that are not one emoji, with the counts they carried: `_skip_reply` (1,365), `_skip_labeling` (857), `_skip_ranking` (396), `red_flag` (48).
emoji_frequency(oasst, text)
#> # A tibble: 2 × 5
#> emoji name shortcode group n
#> <chr> <chr> <chr> <chr> <int>
#> 1 👍 thumbs up +1 People & Body 2323
#> 2 👎 thumbs down -1 People & Body 802