我正在为一系列多项选择考试计算项目统计数据。我有一个使用 mapply 的解决方案,该解决方案在技术上可行,但需要几个小时来计算其中一个更复杂的统计数据。我拥有的第一个数据集是每个学生在每次评估中回答的每个问题都包含一个单独的行。
df <- data.frame(c(rep("s1", 5), rep("s2", 5), rep("s3", 5),rep("s4", 5)),"a1", c("i1", "i2", "i3", "i4", "i5"), c(1, 0), 1)
colnames(df) <- c("student", "assessment", "item", "score", "points.possible")
我要做的第一步(并且只做一次)是创建一个包含所有唯一项目的表。在这种情况下,这很简单,因为只有一个评估和 5 个项目。
unique <- subset(df[,c("assessment", "item")], !duplicated(df[,c("assessment", "item")]))
然后我需要为这些项目中的每一项计算一个统计数据。然而,棘手的部分是计算需要计算学生在整个评估中获得的总分。这是我为此编写的函数。
fun1 <- function(a.id, i.id) {
# subset original dataframe for just one assessment
subsetdf <- df[df$assessment == a.id,]
# generate list of students that got the item right and wrong
correct <- subsetdf$student[subsetdf$item==i.id & subsetdf$score==1]
wrong <- subsetdf$student[subsetdf$item==i.id & subsetdf$score==0]
# scores by student
scores <- aggregate(score ~ student, data=subsetdf,sum)/aggregate(points.possible ~ student, data=subsetdf, sum)
# average scores for students that got item right/wrong
x.1 <- sum(subsetdf$score[subsetdf$student %in% correct])/sum(subsetdf$points.possible[subsetdf$student %in% correct])
x.0 <- sum(subsetdf$score[subsetdf$student %in% wrong])/sum(subsetdf$points.possible[subsetdf$student %in% wrong])
# percent of students that got item right
p <- length(correct)/(length(correct)+length(wrong))
# final stat calculation
r <- ((x.1-x.0)*sqrt(p*(1-p)))/sd(scores[,2])
print(r)
}
然后我使用 mapply 在整个原始数据集上循环这个函数,同时使用较小的数据集作为输入。
unique$r <- mapply(fun1, unique$assessment, unique$item)
我很高兴我能够让它工作,但是当我使用更大的数据集(“df”约 700 万行,“unique”约 2000 行)时,需要相当长的时间(几个小时)。关于解决这个问题的其他更有效方法的任何提示?我了解到一个问题是我的函数每次循环时都会创建原始大型数据集的副本,但我不知道如何解决这个问题没有那个。
我仍然认为自己是 R 的这种用法的初学者,所以任何建议都将不胜感激!