calc_obs = function(X, perspar, empbins = NULL, empcuts = NULL) {

    # Prepare data and person parameters

    data = as.data.frame(apply(X, 2, function(x) {
        x - min(x)
    }))

    if (!is.null(empbins)) {

        if (is.null(empcuts)) {
            quantiles = quantile(perspar, seq(0, 1, length = empbins + 1))
            # SOLLTEN WIR DAS ROUNDEN? SONST PASSIEREN SO DINGE WIE BEI TAM MIT SCIENCE, DASS DIE CUTS
            # NUR ALS RANGE DEFINIERT WERDEN, WEIL DIE UNTERSCHIEDE IN DEN CUTS ZU GERING SIND
            cuts = cut(perspar, unique(round(quantiles, 5)), include.lowest = TRUE)
            if (sum(duplicated(quantiles)) > 0) {
                warning("Some quantiles were not unique and were therefore combined.", call. = FALSE)
            }
        } else {
            message("Both empcuts and empbins specified, empcuts settings will be used.")
            cuts = cut(perspar, empcuts, include.lowest = TRUE)
        }

        sort_perspar = aggregate(perspar, list(cuts), mean, na.rm = TRUE)[, 2]
        ppar = cuts

    } else if (!is.null(empcuts)) {
        cuts = cut(perspar, empcuts, include.lowest = TRUE)
        sort_perspar = aggregate(perspar, list(cuts), mean, na.rm = TRUE)[, 2]
        ppar = cuts
    } else {
        ppar = perspar
        sort_perspar = aggregate(data + 1, by = list(ppar), sum)[, 1]
    }

    # Calculate frequency of choosing a category given the person parameter

    freq_list = lapply(seq_along(colnames(data)), function(x) {
        cats = max(data[, x], na.rm = TRUE) + 1
        n_cat = aggregate(data[, x] + 1, by = list(ppar), tabulate, nbins = cats)  # data must be zero based
        n_cat = n_cat[-1]  # delete the group vector
        freq_cat = n_cat/rowSums(n_cat)
        colnames(freq_cat) = gsub("x", colnames(data)[x], colnames(freq_cat))
        return(freq_cat)
    })

    names(freq_list) = colnames(data)
    attr(freq_list, "sort_perspar") = sort_perspar
    if (!is.null(empbins) | !is.null(empcuts)) {
        attr(freq_list, "cuts") = cuts
    }
    return(freq_list = freq_list)
}

