【问题标题】:R: Problem with calculating mean accuracy with strsplit functionR:使用 strsplit 函数计算平均精度的问题
【发布时间】:2019-05-21 10:45:51
【问题描述】:

我正在尝试根据正确的响应(EQ_CMEM_C 列)计算参与者响应(EQ_RMEM_R 列)的准确性。

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

然后我尝试使用 strsplit 计算准确度,但收到错误通知。

    mean(strsplit(OSPAN$MEM_C, "") == strsplit(OSPAN$MEM_R, ""))
    Error in strsplit(OSPAN$MEM_C, "") == strsplit(OSPAN$MEM_R, "") : comparison of these types is not implemented
    In addition:
    Warning messages:
    1: In strsplit(OSPAN$MEM_R, "") : input string 342 is invalid                             UTF-8
    2: In strsplit(OSPAN$MEM_R, "") : input string 580 is invalid UTF-8

我的问题是:

如何匹配/计算预测变量 (C) 和实际 (R) 值之间的准确度或一致性到总和列中?

例如,在第 1 行中,EQ_SUM 将为 1(或 100%),而在第 2 行中为 0.75 或 75%,因为参与者选择了错误的答案(0 而不是 1)。因此,给出了部分信用评分,这不是绝对匹配/一致的问题。

提前谢谢你。

【问题讨论】:

  • strsplit() 生成一个列表。
  • 你知道我可以用什么代替吗?在计算每一行的准确度分数后,我正在考虑将列表导入原始数据框中。
  • @annedroid 如果 R 和 C 的长度不同,例如第 7 行和第 8 行中的 EQ_C 和 EQ_R
  • 我试图在下面的答案中解决这个问题,但还没有找到结论性的答案。你有什么想法吗? @A.Suliman
  • @annedroid 这里有两个选项使用base::adist 1. apply(OSPAN, 1, function(x) adist(x['EQ_C'], x['EQ_R'])) 这将产生数字方面的差异,2. 或者您可以使用minmax 规范化这些数字,例如:apply(OSPAN, 1, function(x) (max(nchar(x['EQ_C']), nchar(x['EQ_R'])) - adist(x['EQ_C'], x['EQ_R']))/max(nchar(x['EQ_C']), nchar(x['EQ_R'])))

标签: r statistics


【解决方案1】:

一种可能是使用RecordLinkage 库:

with(df, levenshteinSim(EQ_C, EQ_R))

 [1] 1.0000000 0.7500000 1.0000000 1.0000000 1.0000000 1.0000000 0.6666667 0.6666667
 [9] 1.0000000 0.8571429 1.0000000 0.8571429 0.8750000 1.0000000 1.0000000

它使用 Levenshtein 距离计算两个字符串之间的相似度。

【讨论】:

  • 这实际上帮了很多忙,谢谢!尤其是由于编码原因,我在原始帖子中计算 Levensthein 距离的方式不起作用。我假设 [1] 和 [9] 仅显示第 1 行和第 9 行的结果作为示例?
  • 是的,这只是行号。
【解决方案2】:

我确信有一种最有效的方法,但是,您可以逐个列表比较并将其添加到您的数据框中。

for (i in 1:nrow(OSPAN)){
  OSPAN$EQ_SUM[i] <- sum(strsplit(OSPAN$EQ_C, "", useBytes = TRUE)[[i]] == strsplit(OSPAN$EQ_R, "", useBytes = TRUE)[[i]])/length(strsplit(OSPAN$EQ_C, "")[[i]])
  OSPAN$MEM_SUM[i] <- sum(strsplit(OSPAN$MEM_C, "", useBytes = TRUE)[[i]] == strsplit(OSPAN$MEM_R, "", useBytes = TRUE)[[i]])/length(strsplit(OSPAN$MEM_C, "")[[i]])
}

另一方面,有不同长度的案例,我们如何处理它们?

【讨论】:

  • 您好,感谢您的宝贵帮助!当我运行此代码时,我收到每一行的警告: In strsplit(OSPAN$MEM_R, "") : input string 342 is invalid UTF-8 我可以在使用 strsplit 之前更改编码吗?
  • strsplit 处添加参数useBytes = TRUE 应该可以解决这个问题。但是,当两个比较的长度不同时,我们该怎么办?我正在用我告诉你的内容修改我的答案。
  • 我在strsplit 尝试使用useBytes = TRUE 编辑的代码,但不幸的是现在收到以下错误代码:longer object length is not a multiple of shorter object length。这让我想到了你的第二个问题......我在想我可以将字符串长度设置为 N = 10,为所有字符串添加某种虚拟字符。然后我会根据预定义的规则(如果可能)以某种方式剪切字符串,例如:行 1:3 - 4 个字符的长度,行 4:7 - 5 个字符的长度等等。我想那可能是一个循环?很抱歉打扰您!
  • 虽然是错误信息,但它使演算。检查数据帧 OSPAN。 (它表示有多少 R = C,如果 C 多于 R,则假定差值是错误答案)。
  • 是的,这将是一个循环。但没有必要这样做。如果 C >= R,那么,你要做的就是抑制 C 的最后一个值,直到 C = R。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
相关资源
最近更新 更多