Skip to contents

Calculates PPV for each confidence level using all three correction methods (nominal, effective, none) to show the range of plausible PPV estimates.

Usage

ppv_range_by_confidence(
  data,
  lineup_size = 6,
  confidence_bins = NULL,
  effective_size_data = NULL,
  innocent_suspect = "auto",
  base_rate = NULL
)

Arguments

data

A dataframe with columns: target_present, identification, confidence

lineup_size

Integer. Nominal number of people in lineup (default = 6)

confidence_bins

Numeric vector of bin edges (optional)

effective_size_data

Optional pre-computed effective sizes

innocent_suspect

How innocent-suspect identifications in target-absent lineups are obtained. "designated": the lineups had a designated innocent suspect, so target-absent "suspect" rows are counted directly, and zero such rows means a false-ID rate of zero. "estimated": there was no designated innocent suspect, so the innocent-suspect count is estimated as filler IDs divided by lineup_size. "auto" (the default) chooses "designated" when any target-absent row is a suspect ID or the data have a non-missing suspect_pos column, and "estimated" otherwise, with a message.

base_rate

Prior probability that the suspect is guilty. NULL (default) computes PPV from counts, as below. A number strictly between 0 and 1 computes it from the guilty-ID rate (per target-present trial) and the innocent-suspect-ID rate (per target-absent trial) at that prior, so the result does not depend on the TP:TA split.

Value

A list of class "lineup_ppv_range" containing:

  • ppv_range_data: Dataframe with all three PPV estimates per confidence level

  • ppv_nominal: Nominal correction results

  • ppv_effective: Effective size correction results

  • ppv_none: No correction results

  • lineup_size: Nominal lineup size

Details

This function provides the full PPV range recommended by Fitzgerald et al. (2023):

  • Nominal (upper bound): Assumes perfectly fair lineup

  • Effective: Accounts for lineup bias via effective size

  • None (lower bound): Assumes worst-case (all errors are innocent-suspect)

The range between nominal and none represents the uncertainty in PPV due to unknown lineup fairness conditions.

References

Fitzgerald, R. J., Tredoux, C. G., & Juncu, S. (2023). Estimation of eyewitness error rates in fair and biased lineups. Law and Human Behavior.

Examples

data(lineup_example)
# Compute full PPV range
ppv_range <- ppv_range_by_confidence(lineup_example,
                                     confidence_bins = c(0, 60, 80, 100))
#> Target-absent lineups contain a designated innocent suspect, so innocent-suspect IDs are counted directly and no lineup-size correction is applied. The nominal, effective and uncorrected estimates are therefore identical for these data. The three diverge only when no innocent suspect is designated and the number of innocent-suspect IDs has to be estimated from the filler IDs.
print(ppv_range)
#> 
#> === Lineup PPV Range Analysis ===
#> 
#> Lineup size: 6 
#> 
#> Overall PPV by correction method:
#>   Nominal (best-case): 0.825 
#>   Effective (realistic): 0.825 
#>   None (worst-case): 0.825 
#> 
#> PPV range by confidence level:
#>  confidence ppv_nominal ppv_effective ppv_none effective_size error_rate
#>      [0,60]       0.764         0.764    0.764             NA      0.662
#>     (60,80]       0.872         0.872    0.872             NA      1.000
#>    (80,100]       0.962         0.962    0.962             NA      1.000

# Access individual corrections
ppv_range$ppv_nominal$overall_ppv
#> [1] 0.8250497
ppv_range$ppv_effective$overall_ppv
#> [1] 0.8250497
ppv_range$ppv_none$overall_ppv
#> [1] 0.8250497