emoji_seasonality() aggregates emoji use by month of year, day of week or
hour of day. Emoji use is strongly seasonal and strongly diurnal, and both
are confounders worth seeing before any trend is interpreted.
Usage
emoji_seasonality(data, text, time, period = c("month", "weekday", "hour"))Arguments
- data
A data frame or tibble containing a text column. Grouped data frames are accepted. The verbs that work a row at a time (adding columns, or keeping and expanding rows) carry the grouping through to their result, as
dplyr::mutate()anddplyr::filter()do. The verbs that pool across rows – the counts, the co-occurrence edge lists, the time series – warn that they ignore the grouping and return one corpus-wide answer.- text
The text column to scan, supplied unquoted. Any atomic column is accepted and read as character, so a
factorworks and a numeric,Dateor logical one simply contains no emoji. A list column – or a data-frame column – is refused rather than coerced, because coercing one deparses it and the emoji found would be in the code rather than in your data. What counts as an emoji is the same in every verb; see the Detection section of tidyEmoji for the one case that surprises people, code points that are emoji only when they carryU+FE0F.- time
Unquoted column of dates or date-times (
Date,POSIXct, or character in"YYYY-MM-DD"form). A date-time is bucketed by the calendar day it displays as in its own timezone, not by its UTC day: an emoji posted at 23:30 New York time belongs to that day, not to the next one."Its own timezone" means the column's
tzoneattribute. APOSIXctcreated without one – which is whatas.POSIXct("2024-01-01 23:30")and most CSV readers give you – has no timezone of its own, so R displays it in the session's, and the buckets follow. The same column then gives hour 23 on one machine and hour 4 on another. Tag the column (as.POSIXct(x, tz = "UTC"), orlubridate::force_tz()) if the result has to be reproducible; aDatecolumn is immune either way.A character column must lead with a four-digit year:
"2024-01-01"or"2024/01/01", with one- or two-digit month and day, and any trailing time ignored. Values that do not parse warn and are dropped – but a column in which nothing reads as a date is an error rather than a column ofNA, since there would be no time axis left. Note that"01/02/2024"is in the second group: convert a column written that way withas.Date()and its ownformatfirst.- period
"month"(default),"weekday"or"hour"."hour"needs aPOSIXct/POSIXlttime column.
Value
A tibble with one row per level of the cycle: .period (integer:
1-12, 1-7 with Monday first, or 0-23), .period_label, n_texts,
n_with_emoji, n_emoji, emoji_per_text and share (this level's share
of all emoji tokens).
emoji_per_text is n_emoji / n_texts, so the average is over every
text in the level and not only over the ones carrying an emoji. The
distinction is large on a mixed corpus: four emoji spread over three
texts, one of which carries all four, gives 1.33 here and would give
4 the other way. Both denominators are in the table, so divide by
n_with_emoji yourself for the intensity among users of emoji, and read
emoji_per_text as a rate over the whole level. It is NA, not 0,
where the level holds no text at all.
Details
Every level of the cycle is returned, including the empty ones, so a bar chart has no invisible gaps. Labels are fixed English abbreviations rather than locale-dependent ones, so the output of a script does not change with the machine that runs it. Weeks start on Monday.
Rows whose time is missing or unparseable contribute nothing, as in
emoji_trend(). That is worth knowing here in particular, because this
table is complete whether or not the data is: every count in it is over
the dated rows, so sum(n_texts) is the number of rows carrying a
readable time rather than nrow(data), and an emoji sitting in an undated
row reaches neither n_emoji nor share. emoji_summary() counts the
corpus itself if that is what you want to compare against.
See also
emoji_trend() for the calendar-time view.
Examples
df <- data.frame(
when = as.Date(c("2024-01-05", "2024-01-20", "2024-07-03")),
text = c("\U0001f600", "\U0001f600\U0001f602", "plain")
)
emoji_seasonality(df, text, when)
#> # A tibble: 12 × 7
#> .period .period_label n_texts n_with_emoji n_emoji emoji_per_text share
#> <int> <chr> <int> <int> <int> <dbl> <dbl>
#> 1 1 Jan 2 2 3 1.5 1
#> 2 2 Feb 0 0 0 NA NA
#> 3 3 Mar 0 0 0 NA NA
#> 4 4 Apr 0 0 0 NA NA
#> 5 5 May 0 0 0 NA NA
#> 6 6 Jun 0 0 0 NA NA
#> 7 7 Jul 1 0 0 0 0
#> 8 8 Aug 0 0 0 NA NA
#> 9 9 Sep 0 0 0 NA NA
#> 10 10 Oct 0 0 0 NA NA
#> 11 11 Nov 0 0 0 NA NA
#> 12 12 Dec 0 0 0 NA NA