Getting started: import and validate survey data

This article covers installation, loading your first Viva Glint survey export, inspecting the data structure, and joining employee attributes for segmented analysis.

Prerequisites

Install and load vivaglint

Install the package once from GitHub. Required dependencies (dplyr, tidyr, readr, stringr, lubridate, purrr, rlang) install automatically.

install.packages("devtools")
devtools::install_github("microsoft/vivaglint")

Load the package at the start of each R session:

library(vivaglint)

Import a survey export

Use read_glint_survey() to load a Viva Glint CSV export. The function validates the file structure, parses date columns, and returns a glint_survey object ready for analysis.

survey <- read_glint_survey("path/to/survey_export.csv", emp_id_col = "Employee ID")
Parameter Type Default Description
file_path character (required) Path to the Viva Glint CSV export file
emp_id_col character (required) Name of the employee ID column in your export. This varies by organization. The value is stored in the survey object and used automatically by all downstream functions.
encoding character "UTF-8" File encoding. Change to "latin1" if you see garbled characters

read_glint_survey() performs several validation checks automatically:

  • Confirms the file exists and is a valid CSV
  • Verifies all required standard columns are present (see Standard columns)
  • Checks that each question has a complete set of related columns (response, comment, topics, sensitive flag)
  • Parses Survey Cycle Completion Date and Survey Cycle Sent Date from DD-MM-YYYY HH:MM format to date-time values

If validation fails, the function throws a descriptive error message identifying the specific problem. For example, if standard columns are missing, the error lists which columns are absent.

The glint_survey object

read_glint_survey() returns a glint_survey S3 object with two components:

survey$data —a tibble containing all respondent rows and columns from the export.

survey$metadata —a list with:

Field Description
standard_columns Character vector of the standard column names detected at import
emp_id_col The employee ID column name supplied at import (for example, "EMP ID")
questions Tibble with one row per question: question, response_col, comment_col, topics_col, flag_col
n_respondents Integer count of survey rows
n_questions Integer count of survey questions
file_path Original file path used for import

Tip

Inspect the metadata after import to confirm the survey loaded correctly: survey$metadata$n_respondents and survey$metadata$n_questions.

# Check how many respondents and questions were detected
survey$metadata$n_respondents
survey$metadata$n_questions

All vivaglint analysis functions accept both glint_survey objects and plain data frames, so you can pass survey or survey$data interchangeably.

Inspect question names

Before running analysis, use extract_questions() to see exactly how questions are named in your export which is important because analysis functions reference questions by their exact text.

questions <- extract_questions(survey)
print(questions)

The result is a tibble with one row per question:

Column Description
question The question stem text (use in analysis functions)
response_col Column name containing numeric responses
comment_col Column name containing open-ended comments
topics_col Column name containing AI-generated topic tags
flag_col Column name containing sensitive comment flags

Join employee attributes

To segment results by department, job level, tenure, or other attributes, join an employee attribute file to the survey using join_attributes().

survey_enriched <- join_attributes(survey, attribute_source = "employee_attributes.csv")

When survey is a glint_survey object, emp_id_col is resolved automatically from the value you set at import—you don't need to repeat it. If you're passing a plain data frame, supply it explicitly:

survey_enriched <- join_attributes(my_df, "employee_attributes.csv", emp_id_col = "Employee ID")
Parameter Type Default Description
survey glint_survey or data frame (required) The survey object to enrich
attribute_source character or data frame (required) File path to a CSV, or a data frame already in memory
emp_id_col character NULL Name of the employee ID column. Resolved automatically from survey$metadata$emp_id_col when survey is a glint_survey; required when passing a plain data frame.

The attribute file must contain at least two columns: one matching emp_id_col from the survey, and one or more attribute columns (for example, Department, Job Level, Tenure Group).

The function performs a left join—all survey respondents are retained. If a respondent has no match in the attribute file, their attribute columns are set to NA, and a warning is issued.

Note

If you plan to call analyze_by_attributes() or analyze_attrition() multiple times with different attribute combinations, join once with join_attributes() and reuse the enriched survey. This is more efficient than passing an attribute_file on every call.

The enriched object remains a glint_survey, with attribute column names stored in survey_enriched$metadata$attribute_cols for reference.

Two workflows for attribute analysis

Option 1—Join once, reuse:

survey_enriched <- join_attributes(survey, "employees.csv")

# Analyze multiple times without re-joining; emp_id_col resolved from metadata
results_dept   <- analyze_by_attributes(survey_enriched, scale_points = 5,
                                        attribute_cols = "Department")
results_tenure <- analyze_by_attributes(survey_enriched, scale_points = 5,
                                        attribute_cols = "Tenure Group")

Option 2—Join inline (single use):

results <- analyze_by_attributes(
  survey,
  attribute_file = "employees.csv",
  scale_points = 5,
  attribute_cols = "Department"
)

Split survey data

Use split_survey_data() to separate the survey into two streams: numeric responses for statistical analysis, and comment/topic data for qualitative work.

parts <- split_survey_data(survey)

# Numeric responses with standard columns
parts$quantitative

# Comment and topic columns keyed by employee ID
parts$qualitative

The $quantitative component contains all standard respondent columns plus one numeric response column per question. The $qualitative component contains the employee ID column plus all comment, topic, and sensitive flag columns. Employee ID can rejoin both at any time.

This split is useful when you want to pass numeric data to statistical functions while sending comment data to a separate text analysis pipeline.

Standard columns

read_glint_survey() requires the following seven columns at import. If any are missing, the function throws an error identifying which columns are absent.

Column name Description
First Name Respondent first name
Last Name Respondent last name
Email Respondent email address
Status Survey completion status
(your emp_id_col) Employee ID column. The column name varies by organization; specify it via the emp_id_col parameter of read_glint_survey().
Survey Cycle Completion Date Date and time the survey was completed
Survey Cycle Sent Date Date and time the survey invitation was sent

Manager ID isn't required. If it's present in your export, it's recognized and excluded from question detection automatically. You supply the manager ID column name only when calling aggregate_by_manager(), where it's a required parameter.

Next steps