Agreement between two extraction tables, field by field
Source:R/doc-extract-agreement.R
gr_extract_agreement.RdCompares two tables that filled one schema for the same documents: a
model's gr_extract() result against a person's, or two people's. Rows are
matched on the by column and each field is compared on its own, with
Krippendorff's alpha at the level of measurement the field has.
Usage
gr_extract_agreement(
x,
y,
fields = NULL,
levels = NULL,
by = "document",
B = 2000,
conf = 0.95,
seed = 1
)Arguments
- x, y
The two tables:
gr_extract()results, or data frames with abycolumn and one column per field. Which is the reference does not matter, since alpha and percent agreement are symmetric.- fields
Which fields to compare: a character vector of column names, a
gr_fields()schema or agr_protocol(). A schema or protocol also gives each field's type, from which its level and the way its values are read follow.NULLtakes the schema ofx(ory) when it is agr_extract()result, and otherwise every column the two tables share other thanbyand the extraction table's bookkeeping columns.- levels
The level of measurement of each field:
"nominal","ordinal","interval"or"ratio". A character vector named by field, or one unnamed value for every field. A field not named takes its level from its type:"interval"forintegerandnumberfields,"nominal"forstring,enumandbooleanones. An ordinalenumfield is ordered as itsvaluesare declared; the ordinal level is an error for a field with no declared order (astringfield, or a column with no schema that is not numeric or logical). The interval and ratio levels are an error forenumandbooleanfields.- by
The column that names the document in both tables.
- B, conf, seed
Bootstrap resamples for the alpha interval (0 for none), the confidence level, and the seed. The caller's random state is left as it was.
Value
An object of class gr_extract_agreement:
tableOne row per field and part:
field,part,level,n(documents compared),percent_agreement,alpha,lower,upper,not_reported_x,not_reported_y,unknown(matched documents left out because a cell was unknown) andnote, which says why alpha isNAwhen it is.pairsLong form, one row per document and field:
document,field, the two values as text (x,y) and whether each was a value, not reported or unknown (x_state,y_state). Filter it onx != yto read the disagreements.unmatchedThe documents only one table has, as a list with
xandy. They are not compared.notes,conf,bootstrapAs in
hr_agreement().
Not reported
A cell that is empty, NA, or says "not reported", "not stated", "N/A" or
the like is read as the document not reporting the field. In a nominal
field that is one more category, so one side filling a field the other
found unreported is a disagreement like any other. An ordinal, interval or
ratio field cannot place "not reported" on its scale, so it gets two rows:
part = "reported", the nominal agreement on whether the field is reported
at all, and part = "value", the agreement on the value among the
documents where both tables report it. A nominal field has the single row
part = "value".
A cell is unknown, and left out of that field, when the value is there but
cannot be read as the field's type ("120 (60 per arm)" in an integer field,
an undeclared enum value), and in a gr_extract() result when the
document was not read in full: a "failed" or "skipped" row is unknown in
every field, and an empty cell of an "incomplete" row is unknown rather
than not reported. A row that duplicates another document is left out, so
no document counts twice. A data frame with a status column is read the
same way.
How values are compared
A string value is compared after folding case, quote marks, spaces and a
trailing full stop, as gr_extract() does when two parts of one document
give one value two ways. Nothing else is folded, so "RCT" and "randomised
controlled trial" are two values. An enum value is matched to the
declared values ignoring case. Numbers are read as gr_field() describes
and compared exactly, so percent agreement on a numeric field counts
identical values; alpha at the interval or ratio level gives partial credit
for near misses.
Alpha
Krippendorff's alpha is 1 - D_o / D_e, observed over expected disagreement
computed from the coincidence matrix with the difference function of the
level (Krippendorff 2011). Its interval is a percentile bootstrap over
documents (Hayes and Krippendorff 2007). Alpha is reported only when at
least 30 documents are compared and the field is not constant; otherwise it
is NA, note says why, and percent agreement is the figure to read.
Agreement between a model and a person measures how far the model's table
could stand in for a person's, not which of the two is right.
References
Hayes, A. F. and Krippendorff, K. (2007). Answering the call for a standard reliability measure for coding data. Communication Methods and Measures, 1(1), 77-89.
Krippendorff, K. (2011). Computing Krippendorff's alpha-reliability. University of Pennsylvania, Annenberg School for Communication.
Examples
fields <- gr_fields(
design = gr_field("Study design", type = "enum",
values = c("rct", "cohort", "case series")),
n = gr_field("Number randomised", type = "integer")
)
model <- data.frame(document = c("a.pdf", "b.pdf", "c.pdf", "d.pdf"),
design = c("rct", "cohort", "rct", NA),
n = c(120, 85, NA, 40))
person <- data.frame(document = c("a.pdf", "b.pdf", "c.pdf", "d.pdf"),
design = c("RCT", "cohort", "rct", "case series"),
n = c(120, 58, NA, 40))
ag <- gr_extract_agreement(model, person, fields = fields, B = 0)
ag
#> <gr_extract_agreement> 2 field(s), 4 document(s) matched
#>
#> field part level n percent_agreement alpha lower upper not_reported_x
#> design value nominal 4 0.750 NA NA NA 1
#> n reported nominal 4 1.000 NA NA NA 1
#> n value interval 3 0.667 NA NA NA 1
#> not_reported_y unknown
#> 0 0
#> 1 0
#> 1 0
#>
#> Alpha intervals at 95%; bootstrap over documents, B = 0, seed 1.
#> Note (design, value): Only 4 pairable item(s); alpha needs at least 30, so percent agreement is reported instead.
#> Note (n, reported): Only 4 pairable item(s); alpha needs at least 30, so percent agreement is reported instead.
#> Note (n, value): Only 3 pairable item(s); alpha needs at least 30, so percent agreement is reported instead.
subset(ag$pairs, x != y)
#> document field x y x_state y_state
#> 4 d.pdf design not reported case series not reported value
#> 6 b.pdf n 85 58 value value