0

(R, dplyr) 我正在尝试输入学生 MCQ 答案、正确答案和计算分数;许多问题有多个答案。我已将评分表答案 ( ms) 和学生回答 ( sr) 作为数据框输入;列向量是列表。(更新:问题标签是中的行名ms。)

尝试将 sr 的每一列的行与 ms 的相关答案列进行比较以找到:1. 选择的正确答案数量和 2. 是否完全匹配。

我可以将单个元素与length(intersect(sr[[1,2]], ms[[3,2]]))命令进行比较,但我不知道如何扩大规模……通过迭代或 purr、mutate_at 等。

#Sample of the data frame

#Input
ms <- tribble( #mark scheme
  ~q_label, ~point_value,   ~d_partial_credit,  ~c_ans,
  "questions1", 5,  1,  "B,E",
  "questions2", 4,  0,  "C",
  "questions3", 4,  1,  "C,E"
)

ms <- ms %>% remove_rownames %>% column_to_rownames(var="names")


sr <- tribble( #student responses 
~id,    ~questions1,    ~questions2,    ~questions3,
"1", "A,E", "C", "C,B",
"2",    "A,D,E","B","C,E",
"3",    "E",    "C",    "A,B,C",
"4", "E",   "C",    "C"
)

将答案列转换为“字符列表”递归向量事物: ms$c_ans <- lapply(strsplit(as.character(ms$c_ans),split=','),trimws)

makeitlist <- function(x) (lapply(strsplit(as.character(x),split=','),trimws))
for (i in 2:length(sr)) {          
  sr[[i]] <- makeitlist(sr[[i]]) 
}

现在我想在 sr... sr$num_correct1sr$num_correct2等中创建列以指示学生得到了完全匹配,而其他列则指示选择的正确答案的数量...

例如,学生的 sr$questions2 行中的元素数量也在 questions2 的行中ms$c_ans,即在ms[[2,4]]

我认为问题分为两部分:

  1. sr$q1_full <- sr[[2]]==ms[[1,3]]

产生一个很好的布尔向量,但结果令人惊讶(并且不正确,因为我的意图'。为什么FALSE FALSE FALSE TRUE?......应该都是错误的。另外,我怎样才能自动化它以在所有行/列上执行此操作?

  1. length(intersect(sr[[1,2]], ms[[1,3]]))

适用于单个元素,但我怎样才能让它比较整个向量,例如 sr[2] 到 ms[[1,3]]?

4

1 回答 1

0

我找到了主要问题的解决方案;虽然它并不优雅,所以我会很感激其他建议:

将单个响应向量的sr$questions1元素与 ms 的相应元素进行比较,即, ms[[c("questions1"),"c_ans"]]对所有问题和所有学生进行迭代

for(q in rownames(ms)) {   #iterate over all questions 
  for (i in 1:NROW(sr)) {  #over all students
    sr[[glue("cr_ans_",q)]][[i]] <- length(intersect(sr[[q]][[i]], ms[[c(q),"c_ans"]])) 
  }
} 

关键问题是将列表的元素相互比较,而不是将列表本身与元素或相互比较(甚至不是单个元素的列表)。[[]] 至关重要。

'glue' 也有帮助(虽然它不优雅)并且意识到我可以遍历行名。

于 2019-11-03T11:59:51.677 回答