Маркировка MCQ: Как лучше сравнить вектор кадра данных «ответы» со строками элементов «ответы» поэлементно? - PullRequest
0 голосов
/ 02 ноября 2019

(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) </p>

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

СейчасЯ хочу создать столбцы в sr ... sr$num_correct1, sr$num_correct2 и т. Д., Чтобы указать, что ученик получил точное соответствие, и другие, чтобы указать количество выбранных правильных ответов ...

Например, количество элементов в строке ученика sr $ questions2, которые также находятся в строке вопросов2 ms$c_ans, т. Е. В ms[[2,4]]

Я думаю, что проблема разбита на две части:

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

Получает хороший логический вектор, но результаты удивительны (и не правильные, как я предполагал). Почему FALSE FALSE FALSE TRUE? ... должно быть все ложно. Также, как я могу автоматизировать это для всех строк / столбцов?

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

Работает для отдельных элементов, но как мне это сделать, сравнивая целые векторы , такие как sr [2]в мс [[1,3]]?

1 Ответ

0 голосов
/ 03 ноября 2019

Я нашел решение главной проблемы;это не элегантно, поэтому я был бы признателен за другие предложения:

Сравните элементы одного вектора ответов 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"]])) 
  }
} 

Важнейшим вопросом было сравнение элементов списков друг с другом, а не сравнение списков с элементами или друг с другом (даже не спискамиодин элемент). [[]] жизненно важно.

также помог «клей» (хотя и не элегантный), и я понял, что могу перебирать имена строк.

...