Read a DataVolley or VolleyStation file
Usage
dv_read(
filename,
insert_technical_timeouts = TRUE,
do_warn = FALSE,
do_transliterate = FALSE,
encoding = "guess",
date_format = "guess",
extra_validation = 2,
validation_options = list(),
surname_case = "asis",
skill_evaluation_decode = "default",
custom_code_parser,
metadata_only = FALSE,
verbose = FALSE,
edited_meta
)
read_dv(
filename,
insert_technical_timeouts = TRUE,
do_warn = FALSE,
do_transliterate = FALSE,
encoding = "guess",
date_format = "guess",
extra_validation = 2,
validation_options = list(),
surname_case = "asis",
skill_evaluation_decode = "default",
custom_code_parser,
metadata_only = FALSE,
verbose = FALSE,
edited_meta
)Arguments
- filename
string: file name to read
- insert_technical_timeouts
logical or list: should we insert technical timeouts? If TRUE, technical timeouts are inserted at points 8 and 16 of sets 1–4 (for indoor files) or when the team scores sum to 21 in sets 1–2 (beach). Otherwise a two-element list can be supplied, giving the scores at which technical timeouts will be inserted for sets 1–4, and set 5.
- do_warn
logical: should we issue warnings about the contents of the file as we read it?
- do_transliterate
logical: should we transliterate all text to ASCII? This might be helpful when trying to work with multiple files from the same competition, because different text encodings can be used on different files. This can lead to e.g. multiple versions of the same team name. Transliterating can help avoid this, at the cost of losing e.g. diacriticals. Transliteration is applied after converting from the specified text encoding to UTF-8
- encoding
character: text encoding to use. Text is converted from this encoding to UTF-8. A vector of multiple encodings can be provided, and this function will attempt to choose the best. If encoding is "guess", the encoding will be guessed. Common encodings used with DataVolley files include "windows-1252" (western Europe), "windows-1250" (central Europe), "iso-8859-1" (western Europe and Americas), "iso-8859-2" (central/eastern Europe), "iso-8859-13" (Baltic languages)
- date_format
string: the expected date format (one of "ymd", "mdy", or "dmy") or "guess". If
date_formatis something other than "guess", that date format will be preferred where dates are ambiguous- extra_validation
numeric: should we run some extra validation checks on the file? 0=no extra validation, 1=check only for major errors, 2=somewhat more extensive, 3=the most extra checking
- validation_options
list: additional options to pass to the validation step. See
dv_validate()for details- surname_case
string or function: should we change the case of player surnames? If
surname_caseis a string, valid values are "upper","lower","title", or "asis"; otherwisesurname_casemay be a function that will be applied to the player surname strings- skill_evaluation_decode
function or string: if
skill_evaluation_decodeis a string, it can be either "default" (use the default DataVolley conventions for dvw or vsm files), "volleymetrics" (to follow the scouting conventions used by VolleyMetrics), "german" (follows the conventions described in the 2026/27 DVV scouting codebook), or "guess" (use volleymetrics if it looks like a VolleyMetrics file, otherwise default). Ifskill_evaluation_decodeis a function, it should convert skill evaluation codes into meaningful phrases. Seeskill_evaluation_decoder()- custom_code_parser
function: function to process any custom codes that might be present in the datavolley file. This function takes one input (the
datavolleyobject) and should return a list with two named components:playsandmessages- metadata_only
logical: don't process the plays component of the file, just the match and player metadata
- verbose
logical: if TRUE, show progress
- edited_meta
list: if supplied, will be used in place of the metadata present in the file itself. This makes it possible to, for example, read a file, edit the metadata, and re-parse the file but using the modified metadata
Value
An object of class datavolley (which is a named list) with several elements: meta (accessible via the meta() function) provides match metadata, plays (accessible via the plays() function) is the main play-by-play data in the form of a data.frame. raw is the line-by-line content of the datavolley file. messages is a data.frame describing any inconsistencies found in the file. See Details for more information.
Details
The data structure returned by this function is an object of class datavolley. The meta element of this object (accessible via the meta() function) has the following structure. Note that some data frames might have undocumented columns (named as Xn or Vn) - the contents of these are unknown but typically unpopulated or uninformative. "Coordinates" refers to integer coordinates used to encode positions on court, see e.g. dv_xy2index() or https://snippets.openvolley.org/court-plots.html#coordinates.
meta$match: a tibble with columns giving match information:dateDate: match datetimePeriod: match timeseasonstring: free text describing the match seasonleaguestring: free text describing the leaguephasestring: free text describing the match phase (e.g. "Regular season", "Playoffs")home_awaystring: whether the match was a "Home" or "Away" one (text might be in the language of the scout's locale rather than English)day_numbernumeric: day number of the matchmatch_numberstring or numeric: the match identifier, usually used for official league matchestext_encodingstring or numeric: the text encoding of the original file. Thedv_readfunction goes to a lot of effort to detect this and convert the contents of the file to UTF-8, so you should usually not need to do anything with thistext_encodingvalueregulationstring: match regulations, one of "indoor rally point", "beach rally point", or "indoor sideout" (the old scoring system where a team could only score a point while serving)zones_or_conesstring: whether the attack directions have been scouted as zones ("Z") or cones ("C") (see https://snippets.openvolley.org/court-plots.html#plotting-by-cone)
meta$more: a tibble with columns giving information about the match venue and scout:refereesstring: match referee namesspectatorsnumeric: number of spectatorsreceiptsnumeric: not defined in the manualcitystring: name of the cityarenastring: name of the arenascoutstring: name of the person who scouted the match
meta$comments: a tibble with columns:comment_1tocomment_5(some may be missing) string: free text match comments
meta$result: a tibble with columns giving information about the match result, with one row per set played:playedlogical: whether the set was played. Should usually all beTRUE, unplayed sets are automatically removedscore_intermediate1string: the first intermediate score in each set in the format "HS-VS" (home team score and visiting team score). This intermediate score is usually the match score when the first team gets to 8 points for indoor. Different for beach or 5th setsscore_intermediate2string: the second intermediate score in each set in the format "HS-VS" (home team score and visiting team score). This intermediate score is usually the match score when the first team gets to 16 points for indoor. Different for beach or 5th setsscore_intermediate3string: the third intermediate score in each set in the format "HS-VS" (home team score and visiting team score). This intermediate score is usually the match score when the first team gets to 21 points for indoor. Different for beach or 5th setsscorestring: the final set score in the format "HS-VS" (home team score and visiting team score)durationnumeric: set duration in minutesscore_home_teamnumeric: the final home team score in the setscore_visiting_teamnumeric: the final visiting team score in the set
meta$teams: a two-row tibble with columns giving information about the teams:team_idstring: short identifier of the teamteamstring: team namesets_wonnumeric: the number of sets won by the team in the matchcoachstring: name of the head coachassistantstring: name(s) of the assistant coach(es)shirt_colourstring: the team jersey colour in "#RRGGBB" hex formathome_away_teamstring: "*" for the home team and "a" for the visiting teamwon_matchlogical: whether the team won the match
meta$players_h: a tibble with columns giving information about the home team:numbernumeric: player jersey numberstarting_position_set1tostarting_position_set5string: number 1-6 giving their starting position on court if this player was in the starting lineup for this set, or "*" if they were a substitute or liberoplayer_idstring: unique player IDlastnamestring: player last namefirstnamestring: player first namenicknamestring: player nicknamespecial_rolestring: zero or more of "L" (libero) or "C" (captain)rolestring: the player role, one of "libero", "middle", "opposite", "outside", "setter", or "unknown"foreignlogical:TRUEif the player is registered as a foreign playernamestring: a concatenation offirstnameandlastname
meta$players_v: a tibble with columns giving information about the visiting team, with the same structure asmeta$players_hmeta$attacks: a tibble with columns describing attack compound codes:codestring: the two-character attack compound code (e.g. "X1", "V5", "PP")attacker_positionnumeric: the default start zone (1-9) of the attacksidestring: "C"entre, "L"eft, or "R"ighttypestring: a single-character attack tempo ("Q"uick, s"U"per, fas"T", "M"edium, "H"igh, "O"ther)descriptionstring: free text describing the attackcolourstring: the colour in hex format ("#RRGGBB") that can nominally be used to plot this type of attack on an attack chartstart_coordinatenumeric: the start coordinate of the attackset_typestring: a single character describing the set type, one of "F"ront, "C"entre, "B"ack, "P"ipe, or "S"etter dump
meta$sets: a tibble with columns describing setter calls (where the middle hitter has been told by the setter to run their attack):codestring: two-character setter call code (e.g. "K1", "KF")descriptionstring: free text describing the setter callcolourstring: the colour in hex format ("#RRGGBB") that can nominally be used to plot this type of setter call on an attack chartstart_coordinate,mid_coordinate, andend_coordinatenumeric: the start, middle, and end coordinate of a typical path that the middle hitter might take for this setter callpathstring: a comma-separated list of coordinates giving a pathpath_colourstring: the colour in hex format ("#RRGGBB") that can nominally be used to plot the path of this setter call on an attack chart
meta$winning_symbols: a tibble with columns describing whichevaluation_codevalues for a given skill correspond to a winning or losing action:skillstring: single character, one of "S"erve, "R"eception, s"E"t, "A"ttack, "B"lock, "D"ig, "F"reeballwin_losestring: whether thisskillandcodeis a "W"inning or "L"osing actioncodestring: theevaluation_codevalue recorded by the scout, usually one of "#", "=", "/"
meta$match_idstring: a hash computed from (parts of) the match metadatameta$video: a data.frame (usually only one row) giving information about the match video file, if there is one. If no video has been registered to this match file,meta$videoshould have zero rows.camerastring: the camera description, usually "Camera0"filestring: the path to the video file (on the scout's computer)
meta$filenamestring: the file name that was passed todv_read
The plays element of a datavolley object is a data frame that describes events in the match (generally, each ball contact, but also events like timeouts and substitutions). It has this structure:
match_idstring: as formeta$match_idhome_teamstring: the name of the home team in this matchhome_team_idstring: the ID of the home team in this matchvisiting_teamstring: the name of the visiting team in this matchvisiting_team_idstring: the ID of the visiting team in this matchpoint_idnumeric: the rally number in the match. Timeouts will generally be assigned their ownpoint_id. Substitutions will generally be assigned as part of the rally that follows the substitutionteam_touch_idnumeric: a numeric identifier for each set of ball touches made by a team before the ball crosses the net to the other team. A team can make a maximum of 3 ball touches (4 if there was a block touch, for indoor) before the ball must cross the net to the other team. Events with the sameteam_touch_idcorrespond to the same set of 3 team ball touchestimePOSIXct: clock time of the event. This time is recorded by the scouting software, usually as the clock time that the scout entered this code. It might not be an accurate reflection of the actual real-world ball contact time, if the event is a ball contactvideo_file_numbernumeric: the row number of themeta$videodata frame giving the video file details. Only a single video file is currently supported, sovideo_file_numberwill generally be 1 (or missing, if there is no associated video)video_timenumeric: time (in seconds) of this event relative to the start of the videocodestring: the code entered by the scout for this eventteamstring: the name of the team, if this event was associated with a particular teamteam_idstring: the ID of the team, if this event was associated with a particular teamplayer_numbernumeric: the player number, if this event is associated with a particular playerplayer_namestring: the player name, if this event is associated with a particular playerplayer_idstring: the player ID, if this event is associated with a particular playerskillstring: one of "Serve", "Reception", "Set", "Attack", "Block", "Dig", "Freeball", "Timeout", or "Technical timeout"skill_typestring: text describing the type of skill performed (e.g. "Jump serve" or "High ball attack")evaluation_codestring: a single character code entered by the scout that corresponds to the outcome of this ball contact. One of "#", "+", "!", "-", "/", "=". The meaning of each code is not fixed, it is dependent on the associatedskilland the conventions being used by the individual scout. See alsoevaluationevaluationstring: a plain text interpretation of theevaluation_code. The mapping betweenevaluation_codeandevaluationdepends on theskill_evaluation_decodeparameter provided to thedv_read()function, and this should correspond to the conventions being used by the person who scouted the match. The default values are:serve:
"=": "Error"
"-": "Negative, opponent free attack"
"!": "OK, no first tempo possible"
"/": "Positive, no attack"
"+": "Positive, opponent some attack"
"#": "Ace"
reception:
"=": "Error"
"/": "Poor, no attack"
"-": "Negative, limited attack"
"!": "OK, no first tempo possible"
"+": "Positive, attack"
"#": "Perfect pass"
attack:
"=": "Error"
"/": "Blocked"
"-": "Poor, easily dug"
"!": "Blocked for reattack"
"+": "Positive, good attack"
"#": "Winning attack"
block:
"=": "Error" (i.e. an attack kill off the block, not a block fault)
"/": "Invasion" (net touch or other illegal block) or "Poor, opposition to replay" (VolleyMetrics conventions)
"-": "Poor, opposition to replay" or "Poor block" (VolleyMetrics conventions)
"+": "Positive, block touch" or "Positive block" (VolleyMetrics conventions)
"#": "Winning block"
"!": "Poor, opposition to replay" or "Poor, blocking team cannot recover" (VolleyMetrics conventions)
dig:
"=": "Error"
"/": "Ball directly back over net" or "Positive block cover" (VolleyMetrics conventions)
"-": "No structured attack possible"
"!": "OK, no first tempo possible" or "Poor block cover" (VolleyMetrics conventions)
"+": "Good dig"
"#": "Perfect dig"
set:
"=": "Error"
"-": "Poor"
"/": "Poor" (usually a set that crosses the net) or "Error" (VolleyMetrics conventions, a reach over the net)
"!": "OK"
"+": "Positive"
"#": "Perfect"
freeball:
"=": "Error"
"/": "Poor"
"!": "OK, no first tempo possible"
"-": "OK, only high set possible"
"+": "Good"
"#": "Perfect"
attack_codestring: the attack code, only populated ifskillis "Attack" and the attack was scouted using an attack combination code (seemeta$attacks)attack_descriptionstring: the description of the attack (seemeta$attacks), ifattack_codeis populatedset_codestring: the setter call, only populated ifskillis "Set" and the scout recorded a setter call (seemeta$sets)set_descriptionstring: the description of the setter call (seemeta$sets), ifset_codeis populatedset_typestring: theset_type("F"ront, "C"entre, "B"ack, "P"ipe, or "S"etter dump, seemeta$sets), ifattack_codeis populatedstart_zonenumeric: 1-9, the start zone of the event. Note that the conventions used by the DataVolley scouting software are not necessarily the actual start and end locations of the event. For example, the start and end locations of a reception event are assigned to be those of the serve, and similarly digs are as for the corresponding attackend_zonenumeric: 1-9, the end zone of the event. If attacks are being scouted with cones, this column will not be populated for attacksend_subzonestring: the end subzone ("A", "B", "C", or "D") of the event. If attacks are being scouted with cones, this column will not be populated for attacksend_conenumeric: only populated for attacks, and only if the scout is using cones for attack directionsskill_subtypestring: the sub-type of the event. The entries here generally follow the defaults described in the DataVolley software manual, with some adjustments for beach files:attack: "Hard spike", "Soft spike/topspin", or "Tip"
block: "Block assist", "Block attempt", "Block on soft spike" (note that these are rarely used)
reception: "On left", "On right", "Low", "Overhand", "Middle line" (describing how the receiver passed the ball)
set: "1 hand set", "2 hands set", "Bump set", Other set", "Underhand set", (for some beach files) "Hand set"
dig: "Spike cover", "After block", "Emergency", "Tip", "Soft spike"
num_players_numericnumeric: the numeric value entered by the scout for the number of players involved in this eventnum_playersstring: a text description of the number of players involved in this event:attack and block: "No block", "1 player block", "2 player block", "3 player block", "Hole block" or (for beach) "No block", "Line block", "Crosscourt block", "Block jumps to line", "Block jumps to crosscourt"
reception: "Two players receiving, the player on left receives", "Two players receiving, the player on right receives", "Three players receiving, the player on left receives", "Three players receiving, the player in center receives", "Three players receiving, the player on right receives", "Four players receiving, the player on left receives", "Four players receiving, the player on center-left receives", "Four players receiving, the player on center-right receives", "Four players receiving, the player on right receives"
special_codestring: a single character giving an optional special code for this event. The entries here generally follow the defaults described in the DataVolley software manual. A special code entry with an unknown value of "xyz" will appear as "Unexpected xyz":attack (on an error): "Attack out - side", "Attack out - long", "Attack in net", "Net contact", "Referee call", "Antenna"
attack (on an attack kill): "Block out - side", "Block out - long", "Block on floor", "Direct on floor", "Let"
attack (on an attack that remains in play): "Let", "Block control"
block: "Ball out - side", "Ball out - long", "Ball on floor", "Between hands", "Hands - net", "Net contact", "Antenna", "No jump", "Position error", "Referee call"
reception (on an error): "Unplayable", "Body error", "Position error", "Referee call" (e.g. catch and throw), "Lack of effort"
freeball (on an error): "Unplayable", "Body error", "Position error", "Referee call" (e.g. catch and throw)
dig (on an error): "Unplayable", "Body error", "Position error", "Referee call", "Ball on floor", "Ball out", "Lack of effort"
set (on an error): "Cannot be hit", "Net touch", "Referee call" (e.g. double contact)
serve (on an error): "Ball out - long", "Ball out - left", "Ball out - right", "Ball in net", "Referee call" (e.g. foot fault, time violation)
serve (on an ace or a serve that remains in play): "Let"
timeoutlogical:TRUEif this was a timeoutend_of_setlogical:TRUEif this event was the end of a setsubstitutionlogical:TRUEif this event was a substitutionpointlogical:TRUEif this row represents a point being assignedhome_team_scorenumeric: the home team score at the end of this rally (see alsohome_score_start_of_point)visiting_team_scorenumeric: the visiting team score at the end of this rally (see alsovisiting_score_start_of_point)home_score_start_of_pointnumeric: the home team score at the start of this rallyvisiting_score_start_of_pointnumeric: the visiting team score at the start of this rallyhome_setter_positionnumeric: the position on court 1-6 of the home team settervisiting_setter_positionnumeric: the position on court 1-6 of the visiting team settercustom_codestring: an optional custom code (max 5 characters) entered by the scout. The meaning of this code is entirely determined by the individual scoutfile_line_numbernumeric: the line number in the file corresponding to this row in theplaysdatahome_p1tohome_p6numeric: the jersey number of the home team players in positions 1-6 on court. For beach matches, only columnshome_p1andhome_p2will exist. For indoor, note that the libero is never listed here as "on court" because libero entries and exits are not explicitly recorded in the scout file. If the home team libero comes on court for the back-row middle in position 1, thehome_p1value will still be that of the middlehome_player_id1tohome_player_id6string: as forhome_p1tohome_p6, but giving player IDs instead of jersey numbersvisiting_p1tovisiting_p6numeric: as forhome_p1tohome_p6, but for the visiting teamvisiting_player_id1tovisiting_player_id6string: as forvisiting_p1tovisiting_p6, but giving player IDs instead of jersey numbersstart_coordinatenumeric: a single integer giving the start coordinate of the event. Only populated if the scout has entered coordinates, which will typically not be the case in e.g. live-scouted matches (because it is a relatively slow process to do). See alsostart_coordinate_xandstart_coordinate_ystart_coordinate_xandstart_coordinate_ynumeric: separate x- and y-coordinates calculated fromstart_coordinate. See https://snippets.openvolley.org/court-plots.html#background-on-location-information for the coordinate system usedmid_coordinate,mid_coordinate_x,mid_coordinate_ynumeric: as for the start coordinate, but giving the midpoint-coordinate of the event (e.g. if an attack was deflected off the block or the net, a midpoint-coordinate might be recorded)end_coordinate,end_coordinate_x,end_coordinate_ynumeric: as for the start coordinate, but giving the end coordinate of the eventpoint_phasestring: "Breakpoint" (the team associated with this event was the serving team) or "Sideout" (the team associated with this event was the receiving team)attack_phasestring: for attacks, whether the attack occured during "Reception" "Transition breakpoint", or "Transition sideout" phaseset_numbernumeric: the set number (generally 1-5 for indoor, 1-3 for beach)point_won_bystring: the name of the team that won this rallywinning_attacklogical: TRUE if this event was an attack killserving_teamstring: the name of the team that served in this rallyphasestring: one of "Serve" (for serve events), "Reception" (events in the reception phase of play. The reception itself as well as the first set and attack, and the block on that attack are considered to be "Reception" phase), or "Transition" (all events in a rally after the reception-phase events)
Examples
if (FALSE) { # \dontrun{
## to read the example file bundled with the package
myfile <- dv_example_file()
x <- dv_read(myfile, insert_technical_timeouts=FALSE)
summary(x)
## or to read your own file:
x <- dv_read("c:/some/path/myfile.dvw", insert_technical_timeouts=FALSE)
## Insert a technical timeout at point 12 in sets 1 to 4:
x <- dv_read(myfile, insert_technical_timeouts=list(c(12),NULL))
## to read a VolleyMetrics file
x <- dv_read(myfile, skill_evaluation_decode = "volleymetrics")
} # }
