Skip to contents

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() and dplyr::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 factor works and a numeric, Date or 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 carry U+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 tzone attribute. A POSIXct created without one – which is what as.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"), or lubridate::force_tz()) if the result has to be reproducible; a Date column 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 of NA, since there would be no time axis left. Note that "01/02/2024" is in the second group: convert a column written that way with as.Date() and its own format first.

period

"month" (default), "weekday" or "hour". "hour" needs a POSIXct/POSIXlt time 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