如何基于R

时间:2019-05-20 15:21:29

标签: r statistics

我正在尝试根据正确的答案(列C)来计算参与者的答案(列R)的准确性。某些数据以二进制形式(01010-例如,参与者错误,正确,错误,正确,错误)和字母顺序(即字母在字符串中的正确位置)给出。

查看数据示例:

dput(example) 
structure(list(TRIAL = c("1", "2", "3", "4", "5", "6", "7", "8", 
"9", "10", "11", "12", "13", "14", "15"), EQ_C = c("0101", "1010", 
"1010", "00111", "01011", "01101", "100011", "010101", "001101", 
"0110011", "1101001", "1100101", "11100001", "11001010", "11001010"
), EQ_R = c("0101", "0010", "1010", "00111", "01011", "01101", 
"10101", "11010", "001101", "0100011", "1101001", "0100101", 
"11110001", "11001010", "11001010"), MEM_C = c("ZLHK", "RZKX", 
"DGWL", "BCJSP", "WRKTJ", "CHBXS", "HNDCWX", "SWVNDT", "WLDGPB", 
"DSHRKBV", "HCXLZWB", "HDNBVZC", "BCRHKVDM", "RVTBWKFS", "NWHVZFLD"
), MEM_R = c("ZLHK", "RZKX", "DGWL", "BCJSP", "WRKLTJ", "CHBXS", 
"HNDCWX", "SWVDTN", "WLDGPB", "DSHRKBV", "HCXLZWB", "HDNBVZC", 
"BCRHKVDM", "RVTBWKFS", "NWHVZFLD"), EQ_SUM = c(NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), MEM_SUM = c(NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names             
 = c(NA, 
15L), class = "data.frame")

我为需要计算二进制数据(EQ)和字母(MEM)的“总和” /准确性分数添加了新列。

    OSPAN["EQ_SUM"] <- NA
    OSPAN["MEM_SUM"]<- NA

然后,我尝试基于另一个stackoverflow线程(使用预测变量和实际值)来计算总和,但是以某种方式它无法识别我的变量。我怀疑数据格式错误,因为它不断告诉我找不到对象。

example$EQ_SUM <- round(100*rowMeans(EQ_C == EQ_R))

Error in is.data.frame(x) : object 'EQ_C' not found

我的问题是:我如何匹配/计算预测值(C)和实际(R)值之间的准确性或一致性?例如,在第1行中,EQ_SUM为1(或100%),而在第2行中,EQ_SUM为0.75或75%,因为参与者选择了错误的答案(0代替1)。因此,给出了部分信用分数,这不是绝对匹配/一致的问题。

先谢谢您。 (我希望我没有遗漏任何重要信息-这是我第一次发布)。

2 个答案:

答案 0 :(得分:0)

一种简单的计算预测值与实际值的准确度的方法-或者像您的情况下,参与者的响应与实际的响应-通常是这样做的:

mean(EC_C == EC_R, na.rm = TRUE)

其中EC_C和EC_R是包含要为其计算精度的值的列。您将收到一个介于0和1之间的值,后者表示100%的准确性。请注意,在这种情况下,每对单元可以相同或不同。上面计算的准确性将告诉您所有单元对中有多少百分比相同。如果您想比较每对像元中的单个数字,这将不是一种合适的方法-但是目前我还不清楚您要做什么。

更新

下面找到了一种可行的方法,但仅适用于EC_CEC_R具有相同字符数的行。如果答辩人没有回答,也没有记录数字/字符字符串中的哪个数字丢失,则字面上就不可能计算出精度,因为现在还不清楚哪个数字/字符对应于哪个问题数。因此,我的方法的基本假设是,在一个四位数的字符串中,例如EC_C = 1010EC_R = 1000EC_C中的第一位数字映射到EC_R中的第一位数字。对于EC_C = 1010EC_R = 101,不清楚EC_R中的哪个数字映射到EC_C中的哪个数字。可以是左边的前三位数字,精度可以是0.75,也可以是右边的前三位数字,在这种情况下,精度等于0。

除了这一警告之外,我的方法对于所有字符数均相等的行也应适用(假设映射是一致的)。对于所有字符/数字位数不同的行,我的函数将生成NA。如果要使用这种方法评估学生考试的结果,则需要调查每项考试中生成NA的地方,并找出遗漏问题的地方。如果在没有回答的地方插入特殊字符,将来会为您省去很多麻烦。

library(stringr)
example <-
  structure(list(TRIAL = c("1", "2", "3", "4", "5", "6", "7", "8",
                           "9", "10", "11", "12", "13", "14", "15"),
                 EQ_C = c("0101", "1010",
                          "1010", "00111", "01011", "01101", "100011", "010101", "001101",
                          "0110011", "1101001", "1100101", "11100001", "11001010", "11001010"),
                 EQ_R = c("0101", "0010", "1010", "00111", "01011", "01101",
                          "10101", "11010", "001101", "0100011", "1101001", "0100101",
                          "11110001", "11001010", "11001010"),
                 MEM_C = c("ZLHK", "RZKX", "DGWL", "BCJSP", "WRKTJ", "CHBXS", "HNDCWX", "SWVNDT",
                           "WLDGPB",  "DSHRKBV", "HCXLZWB", "HDNBVZC", "BCRHKVDM", "RVTBWKFS", "NWHVZFLD"),
                 MEM_R = c("ZLHK", "RZKX", "DGWL", "BCJSP", "WRKLTJ", "CHBXS",
                           "HNDCWX", "SWVDTN", "WLDGPB", "DSHRKBV", "HCXLZWB", "HDNBVZC",
                           "BCRHKVDM", "RVTBWKFS", "NWHVZFLD"),
                 EQ_SUM = c(NA, NA, NA, NA,NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
                 MEM_SUM = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)),
            row.names = c(NA, 15L), class = "data.frame")

# Function to calculate accuracy
check_accuracy <- function(x,y) {

    # Calculate a matrix which checks if the position of a character in x is corresponding to position in y
    check_mtr = str_split_fixed(x, "", max(nchar(x))) == str_split_fixed(y, "", max(nchar(y)))

    # Calculate the sum of all matching positions
    accuracy_sum = rowSums(check_mtr)

    # Subtract the number of empty strings from accuarcy_sum
    accuracy_sum2 = accuracy_sum - (max(nchar(x)) - nchar(x))

    # Divide sum of all non-empty matching positions by number of non-empty characters
    accuracy_vec = accuracy_sum2 / nchar(x)

    if (any(nchar(x) != nchar(y))) {
    warning("Number of characters in x and y is not corresponding. NAs generated.")
    ifelse(nchar(x) != nchar(y), NA, accuracy_vec)
    } else {
    accuracy_vec
  }

}

example$EQ_SUM <- check_accuracy(example$EQ_C, example$EQ_R)
example$MEM_SUM <- check_accuracy(example$MEM_C, example$MEM_R)
example

更新2: 请注意,此方法计算出的准确性与使用某种字符串距离量度的方法有所不同。当查看MEM_SUM0.5的第8行的结果时,这很清楚,因为受访者只得到正确答案的一半:比较SWVNDTSWVDTN ,前三个答案SWV对应,后三个答案不对应。但是,字符串距离的度量仍然将后三个字符(DTNNDT)视为相关的,因为字母相同,只是顺序不同。此处的字符串距离量度显示为0.67,不对应于0.5的精度。此外,字符串距离方法还将评估未包含答案的响应(字符数不相同的情况)。但是,如果没有指明遗漏了哪个答案,就不可能进行清晰的计算,这就是为什么我的方法在此处分配一个NA以及警告消息的原因。

结果应该像这样

   TRIAL     EQ_C     EQ_R    MEM_C    MEM_R    EQ_SUM MEM_SUM
1      1     0101     0101     ZLHK     ZLHK 1.0000000     1.0
2      2     1010     0010     RZKX     RZKX 0.7500000     1.0
3      3     1010     1010     DGWL     DGWL 1.0000000     1.0
4      4    00111    00111    BCJSP    BCJSP 1.0000000     1.0
5      5    01011    01011    WRKTJ   WRKLTJ 1.0000000      NA
6      6    01101    01101    CHBXS    CHBXS 1.0000000     1.0
7      7   100011    10101   HNDCWX   HNDCWX        NA     1.0
8      8   010101    11010   SWVNDT   SWVDTN        NA     0.5
9      9   001101   001101   WLDGPB   WLDGPB 1.0000000     1.0
10    10  0110011  0100011  DSHRKBV  DSHRKBV 0.8571429     1.0
11    11  1101001  1101001  HCXLZWB  HCXLZWB 1.0000000     1.0
12    12  1100101  0100101  HDNBVZC  HDNBVZC 0.8571429     1.0
13    13 11100001 11110001 BCRHKVDM BCRHKVDM 0.8750000     1.0
14    14 11001010 11001010 RVTBWKFS RVTBWKFS 1.0000000     1.0
15    15 11001010 11001010 NWHVZFLD NWHVZFLD 1.0000000     1.0

答案 1 :(得分:0)

这是使用stringdist软件包的一种方法。

library(stringdist)
library(dplyr)
example %>%
  mutate(EQ_RIGHT  = nchar(EQ_C) - stringdist(EQ_R, EQ_C, method = "lv"),
         EQ_SUM    = EQ_RIGHT / nchar(EQ_C),
         MEM_RIGHT = nchar(MEM_C) - stringdist(MEM_R, MEM_C, method = "lv"),
         MEM_SUM   = MEM_RIGHT / nchar(MEM_C))

“ lv”方法似乎非常适合这里,但还有其他选择。 Levenshtein距离:将字符串a转换为字符串b所需的最少插入,删除和替换。

   TRIAL     EQ_C     EQ_R    MEM_C    MEM_R    EQ_SUM   MEM_SUM EQ_RIGHT MEM_RIGHT
1      1     0101     0101     ZLHK     ZLHK 1.0000000 1.0000000        4         4
2      2     1010     0010     RZKX     RZKX 0.7500000 1.0000000        3         4
3      3     1010     1010     DGWL     DGWL 1.0000000 1.0000000        4         4
4      4    00111    00111    BCJSP    BCJSP 1.0000000 1.0000000        5         5
5      5    01011    01011    WRKTJ   WRKLTJ 1.0000000 0.8000000        5         4
6      6    01101    01101    CHBXS    CHBXS 1.0000000 1.0000000        5         5
7      7   100011    10101   HNDCWX   HNDCWX 0.6666667 1.0000000        4         6
8      8   010101    11010   SWVNDT   SWVDTN 0.6666667 0.6666667        4         4
9      9   001101   001101   WLDGPB   WLDGPB 1.0000000 1.0000000        6         6
10    10  0110011  0100011  DSHRKBV  DSHRKBV 0.8571429 1.0000000        6         7
11    11  1101001  1101001  HCXLZWB  HCXLZWB 1.0000000 1.0000000        7         7
12    12  1100101  0100101  HDNBVZC  HDNBVZC 0.8571429 1.0000000        6         7
13    13 11100001 11110001 BCRHKVDM BCRHKVDM 0.8750000 1.0000000        7         8
14    14 11001010 11001010 RVTBWKFS RVTBWKFS 1.0000000 1.0000000        8         8
15    15 11001010 11001010 NWHVZFLD NWHVZFLD 1.0000000 1.0000000        8         8