This vignette shows how to create visualizations and analyze student
engagement patterns using the engager package.
First, let’s prepare some sample data for analysis:
# Create sample data for demonstration
# In practice, you would load actual transcript and roster data
# Sample transcript metrics
transcripts_metrics_df <- tibble::tibble(
name = c("Alice Johnson", "Bob Smith", "Carol Davis", "David Wilson", "Eva Brown"),
n = c(8, 12, 5, 15, 3),
duration = c(45.2, 67.8, 23.1, 89.4, 12.5),
wordcount = c(1200, 1800, 650, 2200, 400),
comments = list("Good point", "Interesting question", "I agree", "Follow-up question", "Brief comment"),
n_perc = c(18.6, 27.9, 11.6, 34.9, 7.0),
duration_perc = c(19.2, 28.8, 9.8, 38.0, 5.3),
wordcount_perc = c(19.2, 28.8, 10.4, 35.2, 6.4),
wpm = c(26.5, 26.6, 28.1, 24.6, 32.0),
course_section = "LTF.201.1",
course = 201,
section = 1,
day = "Thursday",
time = "18:30",
name_raw = name,
start_time_local = as.POSIXct("2024-01-24 18:30:00", tz = "America/Los_Angeles"),
dept = "LTF",
session_num = 1
)
# Sample roster sessions
roster_sessions <- tibble::tibble(
student_id = c("12345", "12346", "12347", "12348", "12349"),
first_last = c("Alice Johnson", "Bob Smith", "Carol Davis", "David Wilson", "Eva Brown"),
preferred_name = c("Alice", "Bob", "Carol", "David", "Eva"),
dept = "LTF",
course = 201,
section = 1,
session_num = 1,
start_time_local = as.POSIXct("2024-01-24 18:30:00", tz = "America/Los_Angeles"),
course_section = "LTF.201.1"
)
# For this example, we'll work directly with the sample data
# In practice, you would use the essential functions to process authorized data
# Create a simplified summary dataframe for demonstration
transcripts_summary_df <- transcripts_metrics_df %>%
group_by(name) %>%
summarise(
session_ct = n(),
n = sum(n),
duration = sum(duration),
wordcount = sum(wordcount),
n_perc = mean(n_perc),
duration_perc = mean(duration_perc),
wordcount_perc = mean(wordcount_perc),
wpm = mean(wpm),
section = first(section),
course = first(course)
)
# View the summary data
head(transcripts_summary_df)
#> # A tibble: 5 × 11
#> name session_ct n duration wordcount n_perc duration_perc wordcount_perc
#> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Alice… 1 8 45.2 1200 18.6 19.2 19.2
#> 2 Bob S… 1 12 67.8 1800 27.9 28.8 28.8
#> 3 Carol… 1 5 23.1 650 11.6 9.8 10.4
#> 4 David… 1 15 89.4 2200 34.9 38 35.2
#> 5 Eva B… 1 3 12.5 400 7 5.3 6.4
#> # ℹ 3 more variables: wpm <dbl>, section <dbl>, course <dbl>Use the unified plot_users() function to create
visualizations for different engagement metrics. The default output is a
bar chart with a minimal theme for improved readability:
# Plot session count
plot_users(transcripts_summary_df, metric = "session_ct", facet_by = "section", mask_by = "name")# Plot comment count
plot_users(transcripts_summary_df, metric = "n", facet_by = "section", mask_by = "name")# Plot speaking duration
plot_users(transcripts_summary_df, metric = "duration", facet_by = "section", mask_by = "name")# Plot word count
plot_users(transcripts_summary_df, metric = "wordcount", facet_by = "section", mask_by = "name")The package provides several engagement metrics:
Visualize relative participation:
# Plot percentage of comments
plot_users(transcripts_summary_df, metric = "n_perc", facet_by = "section", mask_by = "name")
# Plot percentage of speaking time
plot_users(transcripts_summary_df, metric = "duration_perc", facet_by = "section", mask_by = "name")
# Plot percentage of words
plot_users(transcripts_summary_df, metric = "wordcount_perc", facet_by = "section", mask_by = "name")Focus analysis on enrolled students only:
# Filter for students only (exclude instructors, TAs, etc.)
# In practice, you would use roster data to identify students
students_only_summary <- transcripts_summary_df %>%
filter(!grepl("Instructor|TA|Professor", name, ignore.case = TRUE))
# Plot students-only metrics
plot_users(students_only_summary, metric = "session_ct", facet_by = "section", mask_by = "name")Use rank-based masked labels as one privacy-supporting step. Inspect the source data and finished plot because masking one label column does not review free text, annotations, small groups, or other identifying context:
# Plot with rank-masked names
plot_users(
data = students_only_summary,
metric = "n",
facet_by = "section",
mask_by = "rank"
)
plot_users(
data = students_only_summary,
metric = "duration",
facet_by = "section",
mask_by = "rank"
)Filter data for specific analysis:
# Filter for specific sections
section_data <- transcripts_summary_df %>%
filter(section == 1) # Use the actual section number from our sample data
# Plot filtered data
plot_users(section_data, metric = "wpm", facet_by = "section", mask_by = "name")Compare different metrics:
# Create comparison plots using grid layout
library(gridExtra)
#>
#> Attaching package: 'gridExtra'
#> The following object is masked from 'package:dplyr':
#>
#> combine
# Create individual plots
p1 <- plot_users(transcripts_summary_df, metric = "n", facet_by = "section", mask_by = "name")
p2 <- plot_users(transcripts_summary_df, metric = "duration", facet_by = "section", mask_by = "name")
p3 <- plot_users(transcripts_summary_df, metric = "wordcount", facet_by = "section", mask_by = "name")
p4 <- plot_users(transcripts_summary_df, metric = "wpm", facet_by = "section", mask_by = "name")
# Arrange plots in a grid
grid.arrange(p1, p2, p3, p4, ncol = 2)Look for patterns in participation:
# Analyze participation distribution
participation_summary <- transcripts_summary_df %>%
group_by(section) %>%
summarise(
total_students = n(),
active_students = sum(n > 0),
avg_comments = mean(n),
median_comments = median(n),
participation_rate = active_students / total_students
)
participation_summary
#> # A tibble: 1 × 6
#> section total_students active_students avg_comments median_comments
#> <dbl> <int> <int> <dbl> <dbl>
#> 1 1 5 5 8.6 8
#> # ℹ 1 more variable: participation_rate <dbl>Use the data to create custom visualizations:
# Custom participation distribution
ggplot(transcripts_summary_df, aes(x = n)) +
geom_histogram(binwidth = 1, fill = "steelblue", alpha = 0.7) +
labs(
title = "Distribution of Comment Counts",
x = "Number of Comments",
y = "Number of Students"
) +
theme_minimal()
# Custom duration vs word count
ggplot(transcripts_summary_df, aes(x = duration, y = wordcount)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Speaking Duration vs Word Count",
x = "Duration (seconds)",
y = "Word Count"
) +
theme_minimal()
#> `geom_smooth()` using formula = 'y ~ x'session_ctn or
n_percduration or
duration_percwordcount or wordcount_percwpmvignette("getting-started", package = "engager")vignette("essential-functions", package = "engager")vignette("privacy-ethics-review", package = "engager")