如何对排名顺序测验进行评分以允许 R 中的部分学分

问题描述 投票:0回答:1

现在我有一个包含 23 个测验问题的数据集,受访者必须按照正确的顺序放置指定的步骤。我使用了 Qualtrics,因此数据的输出方式可以告诉我受访者将每个步骤放在 23 个列表中的位置。 这是数据的精简版本

ResponseID  | Step1| Step2 |Step3|.....|Step22|Step23
p1          | 1    | 2     | 3   |.....|22     |23 
p2          | 2    | 3     | 4   |.....|23     |1 
p3          | 2    | 23    | 7   |.....|12     |17 

正确的顺序是数字。因此,任何按顺序排列从 1 到 23 的答案的人都会以正确的顺序获得所有步骤。

实际上,我通过分配分值来对其进行评分,如下所示:

dissdata <- dissdata %>%
  mutate(retention1score = ifelse(dissdata$Q9.2_1 == 1, 1, 0) +
                          ifelse(dissdata$Q9.2_2 == 2, 1, 0) +
                          ifelse(dissdata$Q9.2_3 == 3, 1, 0) +
                          ifelse(dissdata$Q9.2_4 == 4, 1, 0) +
                          ifelse(dissdata$Q9.2_5 == 5, 1, 0) +
                          ifelse(dissdata$Q9.2_6 == 6, 1, 0).................
                          ifelse(dissdata$Q9.2_23 == 23, 1, 0))

基于此,上表中的受访者 p1 的得分为 100% 或 23/23。 受访者 p2 和 p3 得 0 分。但正如您所看到的,受访者 2 比受访者 3 稍微正确一些。受访者 p2 在整个测验中都是一次性的,而受访者 3 则完全错误。

所以,这个 if else 方法适用于非常严格的、全有或全无的评分。但它没有考虑到可能落后了 1 步的人,比如将第 1 步作为第 2 步。我希望能够为落后 1、2 或 3 步分配部分积分。或者对于任何可能正确理解其中大部分内容的人。

如何在 R 中实现这一点? 如果有人能猜出他们是如何完成的,这个链接似乎是一个很好的解决方案:程序化部分信用放入订单分级

谢谢!

r if-statement ranking qualtrics
1个回答
0
投票

“距离”

人们可能会考虑距离函数,其中“完全正确”的距离为零,而其他任何值都小于 100%。解释这种方法有很大的回旋余地,但任何部分得分而不是“错误!0%”都可以被认为是一种更令人安慰的教学方法。

quux <- structure(list(ResponseID = c("p1", "p2", "p3"), Step1 = c(1L, 2L, 2L), Step2 = c(2L, 3L, 23L), Step3 = c(3L, 4L, 7L), Step22 = c(22L, 23L, 12L), Step23 = c(23L, 1L, 17L)), class = "data.frame", row.names = c(NA, -3L))
quux
#   ResponseID Step1 Step2 Step3 Step22 Step23
# 1         p1     1     2     3     22     23
# 2         p2     2     3     4     23      1
# 3         p3     2    23     7     12     17

# you should probably use 1:23, but I only have a subset of data
correct <- c(1, 2, 3, 22, 23)

第一个距离函数严重惩罚(例如)受访者 2 的

Step23
,因为绝对差为
23 - 1 = 22
。数学只是 n 维数据上的毕达哥拉斯数学。我将使用
quux[,-1]
排除
ResponseID
列。

do.call(mapply, c(list(FUN = function(...) sqrt(sum((unlist(list(...)) - correct)^2))), quux[,-1]))
# [1]  0.00000 22.09072 24.37212

这里,

0.000
显然是100%,其他都是各种程度的“不对”。在这个 5 个问题的情况下,最差的分数刚好高于 45.7,其中 Step1=23,Step2=22,...,Step23=1;如果23个都完全落后,那么这里的罚分是

sqrt(sum((1:23 - 23:1)^2))
# [1] 63.62389

如果您认为

22.09072
值得线性部分,如

100 * (63.62389 - do.call(mapply, c(list(FUN = function(...) sqrt(sum((unlist(list(...)) - correct)^2))), quux[,-1]))) / 63.62389
# [1] 100.00000  65.27920  61.69345
### percent

这太仓促了,在接受全权委托之前应该仔细考虑一下。

另一个想法是,你关注的是对/错的存在,而不是距离。也就是说,

Step23=1
的值为 1,
Step23=22
的值为 1,但正确的值为 0。

do.call(mapply, c(list(FUN = function(...) sqrt(sum(unlist(list(...)) != correct))), quux[,-1]))
# [1] 0.000000 2.236068 2.236068

请注意,我们在这里不需要

^2
,因为它始终是
0
1
,所以正方形不执行任何操作。 (如果它让您对这种方法的毕达哥拉斯性质感觉更好,请随意保留它......)

我们可以轻松地用

==
代替
!=
,并且值将是 100% 的
2.236
,但我认为我会与第一部分中开始的反转保持一致。

完全错误的(所有 23 个都相差 1 或更多)只是

sqrt(sum(2:24 != 1:23))
# [1] 4.795832

“最长序列”

您链接的文章从数字来看倾向于“最长的正确排序链”。如果您查看 https://www.r-bloggers.com/2014/09/compute-longest-increasingdecreasing-subsequence-using-rcpp/,这是一种找到数字序列中最长链的方法。

使用它们的功能:

longest_subseq <- function(x) {
    P = integer(length(x))
    M = integer(length(x) + 1)
    L = newL = 0
    for (i in seq_along(x) - 1) {
        lo = 1
        hi = L
        while (lo <= hi) {
            mid = (lo + hi)%/%2
            if (x[M[mid + 1] + 1] < x[i + 1]) {
                lo = mid + 1
            } else {
                hi = mid - 1
            }
        }
        newL = lo
        P[i + 1] = M[newL]
        if (newL > L) {
            M[newL + 1] = i
            L = newL
        } else if (x[i + 1] < x[M[newL + 1] + 1]) {
            M[newL + 1] = i
        }
    }
    k = M[L + 1]
    re = integer(L)
    for (i in L:1) {
        re[i] = k + 1
        k = P[k + 1]
    }
    re
}

然后我们可以找到有多少个数字(每行)的顺序是正确的:

longest_subseq(c(1, 2, 3, 22, 23))
# [1] 1 2 3 4 5  ## length 5, perfect score!
longest_subseq(c(2, 3, 4, 23, 1))
# [1] 1 2 3 4    ## length 4
longest_subseq(c(2, 23, 7, 12, 17))
# [1] 1 3 4 5    ## length 4

并将其自动化为

do.call(mapply, c(list(FUN = function(...) length(longest_subseq(unlist(list(...))))), quux[,-1]))
# [1] 5 4 4

在这种情况下,受访者 1 按正确的顺序拥有所有五个(其中);受访者 2 和 3 只选择了首选相对顺序中的一项。

此方法提供了更清晰的评分:按顺序排列的所有 23 个都是 100%

© www.soinside.com 2019 - 2024. All rights reserved.