
Compute Cut Scores based on Rater's Monotonized Moving Averages
computeCutsIDM.RdCalculates an arbitrary number of cut scores for Item Descriptor Matching (IDM). The number of cuts is determined by the length of the boundaries argument.
Usage
computeCutsIDM(
dat,
boundaries = c(1.5, 2.5, 3.5, 4.5),
est_col = "est",
item_id_col = NULL,
rater_cols = NULL,
rater_pattern = "Rater",
rater_id_col = NULL,
rating_col = NULL,
input_format = c("auto", "long", "wide"),
rating_levels = NULL,
missing = c("drop", "smooth", "error"),
cut_labels = NULL
)Arguments
- dat
A data frame containing item difficulty estimates and rater ratings. Long and wide input formats are supported.
- boundaries
Finite, strictly increasing numeric vector. The cut boundaries on the internal rating scale. For example,
c(1.5, 2.5, 3.5)calculates cuts between four adjacent performance levels.- est_col
Character scalar. Name of the column containing item difficulty estimates. Defaults to
"est".- item_id_col
Optional character scalar. Name of an item identifier column. In long-format input this is used to complete the full item-by-rater grid before smoothing; omitted item-rater combinations are treated as missing ratings. If
NULL,est_colis used as the item identity in long-format input. Supplyitem_id_colwhen different items can share the same difficulty estimate.- rater_cols
Character vector. Names of the rater rating columns for wide-format input. If
NULL, rater columns are selected withrater_pattern.- rater_pattern
Character scalar. Pattern used to find rater rating columns when
rater_cols = NULLin wide-format input. Defaults to"Rater".- rater_id_col
Character scalar. Name of the rater identifier column for long-format input. Rater identifiers may be names or IDs.
- rating_col
Character scalar. Name of the rating column for long-format input. Values may be numeric or ordinal labels when
rating_levelsis supplied.- input_format
Character scalar. One of
"auto","long", or"wide". In"auto"mode, the function uses long format when bothrater_id_colandrating_colare supplied, and wide format when neither is supplied. Supplying only one of these arguments is an error.- rating_levels
Optional atomic vector defining the ordered rating scale, for example
c("1a", "1b", "2", "3", "4"). Supplied levels, including numeric levels, are mapped to consecutive stages starting at 1. Non-numeric ratings require this argument. Ifboundariesis not supplied, adjacent boundaries are derived from these levels.- missing
Character scalar.
"drop"removes missing ratings before smoothing each rater's remaining sequence; the corresponding rows stay missing in the smoothed and isotonic series."smooth"retains the full sequence and averages available values in each three-point window, potentially producing a smoothed value at a missing rating."error"rejects missing ratings, including omitted long-format item-rater combinations. See Details for short sequences and empty windows.- cut_labels
Optional character vector with one label per boundary. Labels must be unique and start with
"cut"so thatplotCutsIDM()remains compatible.
Details
The function supports two input formats. In long format, each row contains one item-rater combination and the columns identified by est_col, rater_id_col, and rating_col. In wide format, each row contains one item and one or more rater rating columns. Wide-format input keeps the previous default behavior.
Long-format input is completed internally to the full item-by-rater grid before smoothing. Thus an omitted item-rater row is interpreted like an explicit missing rating, not like a removed item. If item_id_col is supplied, it defines the item identity used for this completion. If it is not supplied, est_col is used as a fallback item identity; this requires at most one rating per rater and difficulty value. When multiple distinct items may have identical difficulty estimates, item_id_col should be supplied.
All input is normalized internally to a long representation with item difficulty, rater identifier, and numeric rating stage. Whenever rating_levels is supplied, its entries define the ordinal order and are mapped to 1, 2, ..., k for computation, even if the entries are numeric. Without rating_levels, numeric ratings are used unchanged.
The smoothing padding and plot scale are based on the observed rating scale and the supplied boundaries. Missing ratings are handled according to missing. The default "drop" is conservative: missing ratings do not create smoothed values. The "smooth" option uses the legacy-like moving average behavior where missing values inside the smoothing window are ignored.
The function processes each rater by:
Sorting items by difficulty (
est_col).Applying a symmetric three-point moving average (order = 1) with the padding values defined below, unless the sequence to be smoothed has fewer than three entries.
Applying isotonic regression (
isoreg) to ensure the mapping of difficulty to level is non-decreasing.Computing the cut score as the linearly interpolated item difficulty where the monotonized function crosses the specified boundary.
More formally, for a rater let \(x_i\) denote the item difficulty estimate and \(r_i\) the rating stage after conversion to the internal numeric scale. Items are first ordered such that \(x_1 \leq \ldots \leq x_n\). Tied difficulties retain the order in which the items first occur in the input for smoothing. If ordinal labels are used, rating_levels defines the mapping to this internal scale; for example c("1a", "1b", "2", "3", "4") is mapped to \(1, 2, 3, 4, 5\). Boundaries are specified on this internal scale, so 2.5 is the boundary between the second and third ordered rating level.
The smoothed value \(z_i\) is a symmetric moving average of order 1. For a sequence of at least three entries without missing values this is
$$
z_i = \frac{r_{i-1} + r_i + r_{i+1}}{3},
$$
using padding values \(r_0 = L_{\min}\) and \(r_{n+1} = L_{\max}\) at the lower and upper end of the ordered series. Let \(R\) contain all finite internal ratings across all raters and \(B\) the supplied (or automatically derived) boundaries. The shared padding values are
$$
L_{\min} = \min\{\min R, \lfloor\min B\rfloor\},
\qquad
L_{\max} = \max\{\max R, \lceil\max B\rceil\}.
$$
They are returned as min_val and max_val and also define the plot range. They are not computed separately for each rater. The function rejects input with no finite ratings at all.
With missing = "drop", the moving average is applied to the compressed sequence of finite ratings. Thus the neighbors are the previous and next available ratings, possibly spanning missing items. The result is then placed back at the original item positions; missing rows remain missing in the smoothed and monotonized series. With missing = "smooth", the full item sequence is retained and each window is averaged over its non-missing entries (including padding at the ends). This can fill a missing rating's smoothed value, but a window with no available entries yields NA. Smoothing is a single pass over the raw stages, not a recursive imputation. For fewer than three entries in the sequence being smoothed, values are returned unchanged and no padding is applied: this counts finite ratings for "drop" and all items for "smooth".
The monotonized series \(\hat y_i\) is the isotonic least-squares fit
$$
\hat y = \arg\min_{y_1 \leq \ldots \leq y_n} \sum_i (z_i - y_i)^2,
$$
computed with isoreg on finite smoothed values, with equal weight per retained item and the additional constraint \(y_i = y_j\) whenever \(x_i = x_j\). The indices in this expression refer only to these retained values. Tied difficulty estimates receive the same fitted value. This step forces the estimated relationship between item difficulty and rating stage to be non-decreasing; distances between difficulty estimates do not weight the fit. If fewer than two finite smoothed values remain, the entire isotonic series and all cuts for that rater are NA.
For each boundary \(b\), the function searches the finite fitted points and finds the first ordered point \(i\) with \(\hat y_i \geq b\). If no such point exists, the cut is NA; the function does not extrapolate above the fitted range. If \(i = 1\), the cut and its item position are those of the first retained point, including when the boundary is below the fitted range. Otherwise the cut is linearly interpolated between the two surrounding retained points:
$$
\lambda = \frac{b - \hat y_{i-1}}{\hat y_i - \hat y_{i-1}},
\quad
c_b = x_{i-1} + \lambda (x_i - x_{i-1}).
$$
cuts_per_person stores \(c_b\), i.e. the cut on the item difficulty scale. The same interpolation factor is applied to the ordered item positions \(p_i\) to obtain
$$
q_b = p_{i-1} + \lambda (p_i - p_{i-1}),
$$
which is stored in cut_positions_per_person. Here \(p_i\) is the position in the full ordered item list, even when missing ratings have been dropped. These positions can be non-integer, and interpolation can span missing items. If the boundary equals a fitted plateau, the first point on that plateau is used.
Cut score columns start with cut. Canonical numeric boundaries such as 1.5 and 2.5 are labelled as cut12 and cut23 for numeric ratings. With ordinal labels, labels such as cut_1a_1b are used. Non-canonical boundaries include the boundary value, for example cut_1a_1b_bound1_3.
cut_statistics reports the mean, sample standard deviation, and standard error across raters for both item positions (page_*) and difficulty cuts (diff_*). Standard errors are computed as \(SE = SD / \sqrt{m}\), where \(m\) is the number of finite rater-specific cuts for that boundary. SD and SE are NA for fewer than two finite cuts; the mean is also NA if none exist. cuts_summary contains the unweighted mean difficulty cut per boundary, omitting missing cuts. These are means of individual cuts, not cuts computed from an averaged rating curve, and the contributing raters can differ by boundary. level_statistics uses the finite mean cuts as interval boundaries between the minimum and maximum item difficulty, counts each item once (including items with missing ratings), and reports the mean and sample standard deviation of item difficulties per level. Unavailable mean cuts are omitted. Intervals are left-closed and right-open, except for the final interval, which is closed on both sides. Empty intervals have NA means and SDs; intervals with one item have an NA SD.
The object also contains descriptive agreement diagnostics computed from the raw internal rating stages after the input has been normalized to the complete item-by-rater grid. These diagnostics do not enter the cut-score interpolation itself. modal_values reports the modal rating stage for each item. If several stages are tied for the highest frequency, modal_stage and modal_label are set to NA, while modal_stages, modal_labels, and tie retain the tie information. rater_modal_correlations correlates each rater's raw rating series with the item-wise modal values. It reports the correlation with the modal values based on all raters and, additionally, with leave-one-rater-out modal values so that the evaluated rater does not help define the criterion. Items without a unique modal value are omitted from the corresponding correlation.
Pairwise unweighted Cohen's kappa values are computed with meanKappa on the wide raw-rating matrix, using complete observations separately for each rater pair. kappa_summary gives the unweighted mean and sample standard deviation across finite pairwise kappa values, and rater_kappa_statistics gives the same information per rater across all pairings involving that rater. fleiss_kappa and icc_statistics are computed on item rows complete across all raters. The ICCs use a two-way model with single-measure agreement and consistency estimates. These diagnostics use raw ratings even with missing = "smooth"; smoothed values do not fill missing observations for agreement calculations. They summarize the rating round represented by the supplied data; the function does not select a round automatically. If the third IDM round should be analyzed, the input should contain that final round.
In plot_data, the residual is \(r_i - z_i\), the raw rating minus its moving average, rather than minus the isotonic fit.
Value
A cutsIDM object, i.e. a named list with:
cuts_per_personOne row per rater and one difficulty-scale cut column per boundary. Each cut is the first boundary crossing of that rater's smoothed, isotonic rating series, with linear interpolation on the difficulty scale as specified in Details. Unreached boundaries and raters with fewer than two finite smoothed values yield
NA.cut_positions_per_personThe same crossings expressed as positions in the full difficulty-ordered item list. The interpolation factor used for the difficulty cut is applied to the two surrounding item positions; missing items retain their positions in this list. Columns are named
page_*.cuts_summaryOne row of unweighted arithmetic means of the finite rater-specific difficulty cuts, computed separately for each boundary. A boundary with no available cuts has mean
NA.cut_statisticsRows
Mean,SD, andSEfor item-position cuts (page_*) and difficulty cuts (diff_*). For each column, \(m\) finite cuts contribute to the arithmetic mean, the sample SD fromsd(denominator \(m-1\)), and \(SE = SD / \sqrt{m}\). SD and SE areNAfor \(m < 2\); all three statistics areNAfor \(m = 0\).level_statisticsIntervals formed from the minimum item difficulty, the finite mean cuts in boundary order, and the maximum item difficulty. For each interval,
n_itemscounts distinct items, andmean_itemdiffandsd_itemdiffare their arithmetic mean and sample SD. Items at a cut enter the interval starting at that cut; the final interval also includes its upper endpoint. Empty intervals haveNAmeans and SDs, and one-item intervals haveNASDs.modal_valuesItem-wise modes of the available raw internal rating stages.
n_ratingscounts available ratings,modal_nis the highest category count, andmodal_prop = modal_n / n_ratings. A unique mode is returned inmodal_stageandmodal_label. Ties set these two fields toNA, whilemodal_stages,modal_labels, andtieretain the tied modes. Items without ratings haven_ratings = 0, missing mode fields and proportions, andtie = FALSE.rater_modal_correlationsPearson correlations computed with
stats::corbetween each rater's raw numeric stages and the unique item modes.cor_modal_alluses modes from all raters;cor_modal_leave_one_outrecomputes each mode without the evaluated rater. Each correlation uses only items with both a finite rating and a unique mode; the correspondingn_items_*column gives that count. Fewer than two usable items or zero variance in either series yieldsNA.kappa_pairwiseOne row per available rater pair, with
Coder1,Coder2, the numberNof jointly rated items, andkappa. The callmeanKappa(ratings, weight.mean = FALSE)usesirr::kappa2withweight = "unweighted"on each pair's complete raw ratings. Thus $$\kappa = \frac{p_o - p_e}{1 - p_e}, \qquad p_e = \sum_k p_{1k}p_{2k}.$$ Here \(p_o\) is the proportion of exact agreements and \(p_{1k}, p_{2k}\) are the two raters' marginal proportions for category \(k\) on those items. All disagreements receive the same weight. Pairs without jointly rated items are omitted. As a special convention inmeanKappa, an undefined kappa is replaced by 1 when the two retained rating vectors are identical. Fewer than two raters, no available pairs, or an error in themeanKappa()call yields an empty table. Althoughirr::kappa2()computes a significance test, its test statistic and p-value are not retained in this component.kappa_summarymean_kappaandsd_kappaare the arithmetic mean and sample SD of the finite entries inkappa_pairwise$kappa, withn_pairsgiving their count. Every pair has equal weight, regardless ofN.mean_n_itemsaveragesNover all returned pair rows, including rows with non-finite kappa. With no finite kappas, mean and SD areNA; with one finite kappa, SD isNA.rater_kappa_statisticsThe same calculations as in
kappa_summary, restricted to pairs involving the respective rater.n_pairscounts finite kappas;mean_n_itemsaverages item counts over all returned pairs involving that rater.fleiss_kappaOne row from
irr::kappam.fleisson raw-rating rows complete across all raters, using the defaultsexact = FALSEanddetail = FALSE. For \(n\) complete items, \(J\) raters, and category counts \(n_{ik}\) within item \(i\), $$P_i = \frac{\sum_k n_{ik}(n_{ik}-1)}{J(J-1)}, \quad p_k = \frac{\sum_i n_{ik}}{nJ}, \quad \kappa = \frac{\bar P - \sum_k p_k^2}{1 - \sum_k p_k^2}.$$ Here \(\bar P\) is the mean of \(P_i\). This uses pooled category proportions.kappa,statistic, andp_valuecontain the coefficient, the z statistic, and its two-sided p-value for zero kappa returned byirr.n_itemsandn_ratersrecord the matrix dimensions. Fewer than two complete items or raters yieldsNAestimates; calculation errors or non-finite results also yieldNA.The test evaluates \(H_0: \kappa = 0\) against \(H_1: \kappa \ne 0\). A significant
p_valueat the chosen significance level indicates agreement differing from that expected under the pooled category proportions: above chance for a positive kappa, below chance for a negative kappa. Significance alone does not establish strong agreement; interpret the magnitude and sign ofkappaas well.icc_statisticsTwo rows from
irr::iccon raw-rating rows complete across all raters:model = "twoway",unit = "single", andtype = "agreement"or"consistency". These giveICC(A,1)andICC(C,1). With \(n\) complete items, \(J\) raters, and two-way ANOVA mean squares \(MS_I\) (items), \(MS_R\) (raters), and \(MS_E\) (residual error), $$ICC(A,1) = \frac{MS_I-MS_E}{MS_I+(J-1)MS_E+\frac{J}{n}(MS_R-MS_E)},$$ $$ICC(C,1) = \frac{MS_I-MS_E}{MS_I+(J-1)MS_E}.$$ Agreement includes systematic differences between raters' means; consistency removes that component. The returnedf_value,df1,df2, andp_valuecome fromirr's F-test with defaultr0 = 0;conf_level,lbound, andubounddescribe its default 95% confidence interval.n_itemsandn_ratersrecord the matrix dimensions. Fewer than two complete items or raters, calculation errors, and non-finite results yieldNAin the corresponding estimate fields.Each row tests \(H_0: ICC = 0\) against the one-sided alternative \(H_1: ICC > 0\). A significant
p_valueprovides evidence for positive reliability under the respective agreement or consistency definition. Withr0 = 0and non-degenerate data, both tests use the same F statistic and degrees of freedom, so their p-values coincide even when the ICC estimates differ. These tests do not test equality of rater means or a difference between the two ICCs. Assess whether reliability is practically adequate using the ICC estimate and its confidence interval; significance alone does not establish that.plot_dataLong-format item identifiers and positions, raw internal stages (
stage_raw), moving averages (stage_sm), isotonic fits (stage_iso), and residualsstage_resid = stage_raw - stage_sm, used byplotCutsIDM(). The smoothing and fitting steps are defined in Details.- Metadata
boundaries,cut_labels,min_val,max_val,est_col,item_id_col,rater_cols, and further input settings used byplotCutsIDM().min_valandmax_valare the shared padding values defined in Details.
All modal, correlation, kappa, and ICC results use raw internal rating stages; smoothing does not impute missing ratings for these diagnostics.
Only fleiss_kappa and icc_statistics include significance tests in the returned object. The other components, including the modal correlations and pairwise kappa summaries, are descriptive and do not report p-values.
summary() can be used to print the main cut score, boundary, and level-statistic tables in a compact form.
Examples
## Wide-format input with numeric rating stages
dat <- data.frame(
est = seq(100, 800, by = 100),
Rater1 = c(1, 1, 2, 2, 3, 3, 4, 5),
Rater2 = c(1, 2, 2, 3, 3, 4, 4, 5)
)
cuts <- computeCutsIDM(dat, boundaries = c(1.5, 2.5, 3.5))
cuts$cuts_per_person
#> # A tibble: 2 × 4
#> person cut12 cut23 cut34
#> <chr> <dbl> <dbl> <dbl>
#> 1 Rater1 250 450 625
#> 2 Rater2 150 350 550
cuts$cuts_summary
#> # A tibble: 1 × 3
#> cut12 cut23 cut34
#> <dbl> <dbl> <dbl>
#> 1 200 400 588.
cuts$cut_statistics
#> # A tibble: 3 × 7
#> statistic page_cut12 page_cut23 page_cut34 diff_cut12 diff_cut23 diff_cut34
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Mean 2 4 5.87 200 400 588.
#> 2 SD 0.707 0.707 0.530 70.7 70.7 53.0
#> 3 SE 0.5 0.5 0.375 50 50 37.5
cuts$level_statistics
#> # A tibble: 4 × 5
#> level interval n_items mean_itemdiff sd_itemdiff
#> <int> <chr> <int> <dbl> <dbl>
#> 1 1 [100,200) 1 100 NA
#> 2 2 [200,400) 2 250 70.7
#> 3 3 [400,587.5) 2 450 70.7
#> 4 4 [587.5,800] 3 700 100
cuts$modal_values
#> # A tibble: 8 × 11
#> item_position item_id est n_ratings modal_n modal_prop modal_stage
#> <int> <chr> <dbl> <int> <int> <dbl> <dbl>
#> 1 1 1 100 2 2 1 1
#> 2 2 2 200 2 1 0.5 NA
#> 3 3 3 300 2 2 1 2
#> 4 4 4 400 2 1 0.5 NA
#> 5 5 5 500 2 2 1 3
#> 6 6 6 600 2 1 0.5 NA
#> 7 7 7 700 2 2 1 4
#> 8 8 8 800 2 2 1 5
#> # ℹ 4 more variables: modal_label <chr>, modal_stages <chr>,
#> # modal_labels <chr>, tie <lgl>
cuts$rater_kappa_statistics
#> # A tibble: 2 × 5
#> person n_pairs mean_kappa sd_kappa mean_n_items
#> <chr> <int> <dbl> <dbl> <dbl>
#> 1 Rater1 1 0.529 NA 8
#> 2 Rater2 1 0.529 NA 8
cuts$fleiss_kappa
#> # A tibble: 1 × 6
#> method n_items n_raters kappa statistic p_value
#> <chr> <int> <int> <dbl> <dbl> <dbl>
#> 1 Fleiss 8 2 0.525 2.90 0.00369
cuts$icc_statistics
#> # A tibble: 2 × 14
#> type model unit n_items n_raters icc_name icc f_value df1 df2 p_value
#> <chr> <chr> <chr> <int> <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 agree… twow… sing… 8 2 ICC(A,1) 0.901 26.6 7 7 1.57e-4
#> 2 consi… twow… sing… 8 2 ICC(C,1) 0.928 26.6 7 7 1.57e-4
#> # ℹ 3 more variables: conf_level <dbl>, lbound <dbl>, ubound <dbl>
summary(cuts)
#> IDM cut-score summary
#>
#> Settings
#> input_format missing est_col item_id_col n_raters n_items n_cuts
#> wide drop est <NA> 2 8 3
#>
#> Boundaries
#> cut boundary lower_level upper_level
#> cut12 1.5 1 2
#> cut23 2.5 2 3
#> cut34 3.5 3 4
#>
#> Mean cuts on difficulty scale
#> cut12 cut23 cut34
#> 200 400 587.5
#>
#> Cut statistics
#> statistic page_cut12 page_cut23 page_cut34 diff_cut12 diff_cut23 diff_cut34
#> Mean 2.00 4.00 5.87 200.00 400.00 587.50
#> SD 0.71 0.71 0.53 70.71 70.71 53.03
#> SE 0.50 0.50 0.37 50.00 50.00 37.50
#>
#> Level statistics
#> level interval n_items mean_itemdiff sd_itemdiff
#> 1 [100,200) 1 100 NA
#> 2 [200,400) 2 250 70.71
#> 3 [400,587.5) 2 450 70.71
#> 4 [587.5,800] 3 700 100.00
#>
#> Modal values per item
#> item_position item_id est n_ratings modal_n modal_prop modal_stage modal_label
#> 1 1 100 2 2 1.0 1 1
#> 2 2 200 2 1 0.5 NA <NA>
#> 3 3 300 2 2 1.0 2 2
#> 4 4 400 2 1 0.5 NA <NA>
#> 5 5 500 2 2 1.0 3 3
#> 6 6 600 2 1 0.5 NA <NA>
#> 7 7 700 2 2 1.0 4 4
#> 8 8 800 2 2 1.0 5 5
#> modal_stages modal_labels tie
#> 1 1 FALSE
#> 1/2 1/2 TRUE
#> 2 2 FALSE
#> 2/3 2/3 TRUE
#> 3 3 FALSE
#> 3/4 3/4 TRUE
#> 4 4 FALSE
#> 5 5 FALSE
#>
#> Rater correlations with modal values
#> person n_items_modal_all cor_modal_all n_items_modal_loo
#> Rater1 5 1 8
#> Rater2 5 1 8
#> cor_modal_leave_one_out
#> 0.93
#> 0.93
#>
#> Pairwise Cohen kappa summary
#> n_pairs mean_kappa sd_kappa mean_n_items
#> 1 0.53 NA 8
#>
#> Rater pairwise Cohen kappa
#> person n_pairs mean_kappa sd_kappa mean_n_items
#> Rater1 1 0.53 NA 8
#> Rater2 1 0.53 NA 8
#>
#> Fleiss kappa
#> method n_items n_raters kappa statistic p_value
#> Fleiss 8 2 0.52 2.9 0
#>
#> ICC agreement and consistency
#> type model unit n_items n_raters icc_name icc f_value df1 df2
#> agreement twoway single 8 2 ICC(A,1) 0.90 26.6 7 7
#> consistency twoway single 8 2 ICC(C,1) 0.93 26.6 7 7
#> p_value conf_level lbound ubound
#> 0 0.95 0.53 0.98
#> 0 0.95 0.68 0.99
## Long-format input with ordinal rating labels
long_dat <- data.frame(
item = rep(paste0("item_", 1:5), 2),
theta = rep(seq(100, 500, by = 100), 2),
rater = rep(c("Meyer", "Schmidt"), each = 5),
rating = c(
"1a", "1b", "2", "3", "4",
"1a", "1b", "2", "3", "4"
)
)
ord_cuts <- computeCutsIDM(
long_dat,
item_id_col = "item",
est_col = "theta",
rater_id_col = "rater",
rating_col = "rating",
rating_levels = c("1a", "1b", "2", "3", "4")
)
ord_cuts$cuts_summary
#> # A tibble: 1 × 4
#> cut_1a_1b cut_1b_2 cut_2_3 cut_3_4
#> <dbl> <dbl> <dbl> <dbl>
#> 1 125 250 350 475
ord_cuts$modal_values
#> # A tibble: 5 × 11
#> item_position item_id est n_ratings modal_n modal_prop modal_stage
#> <int> <chr> <dbl> <int> <int> <dbl> <dbl>
#> 1 1 item_1 100 2 2 1 1
#> 2 2 item_2 200 2 2 1 2
#> 3 3 item_3 300 2 2 1 3
#> 4 4 item_4 400 2 2 1 4
#> 5 5 item_5 500 2 2 1 5
#> # ℹ 4 more variables: modal_label <chr>, modal_stages <chr>,
#> # modal_labels <chr>, tie <lgl>
names(ord_cuts$cuts_per_person)
#> [1] "person" "cut_1a_1b" "cut_1b_2" "cut_2_3" "cut_3_4"