data.table中的ifelse赋值

时间:2016-10-28 23:35:36

标签: r data.table

我是一名教师,并希望正确使用data.table中的R包在日志文件中自动评分学生答案,即如果学生添加名为correct的列回答一个特定问题,是该问题的正确答案,否则为0。如果每个问题只有一个答案,我可以很容易地做到这一点,但如果一个问题有多个可能的答案(问题及其可能的正确答案存储在另一个表中),我就会被绊倒。

以下是MWE:

set.seed(123)
question_table <- data.table(id=c(1,1,2,2,3,4),correct_ans=sample(1:4,6,replace = T))
log <- data.table(student=sample(letters[1:3],10,replace = T),
                  question_id=c(1,1,1,2,2,2,3,3,4,4), 
                  student_answer= c(2,4,1,3,2,4,4,5,2,1))

我的问题在于data.table中使用ifelse的正确j方式是什么,特别是如果我们依赖另一个表格?

log[,correct:=ifelse(student_answer %in% 
                          question_table[log$question_id %in% id]$correct_ans,1,0)]

如下所示,问题1和2都有多个可能的正确答案。

> question_table
   id correct_ans
1:  1           2
2:  1           4
3:  2           2
4:  2           4
5:  3           4
6:  4           1

虽然正确的列计算没有错误,但有些事情是不对的:例如当student b回答问题时,即使答案不正确,他也会获得正确的分数。只有correct列的某些条目处于关闭状态,这使我相信有些内容我没有了解变量的范围。

> log
    student question_id student_answer correct
 1:       b           1              2       1
 2:       c           1              4       1
 3:       b           1              1       1   <- ?
 4:       b           2              3       0
 5:       c           2              2       1
 6:       b           2              4       1
 7:       c           3              4       1
 8:       b           3              5       0
 9:       a           4              2       1   <- ?
10:       c           4              1       1

我考虑通过logjoinquestion_table表格中使用正确的ans创建一个帮助列,但这不起作用,因为密钥在后者中不是唯一的。

任何和所有帮助将不胜感激。 提前谢谢。

1 个答案:

答案 0 :(得分:6)

您可以使用加入:

# initialize to zero
log[, correct := 0L ]

# update to 1 if matched
log[question_table, on=c(question_id = "id", student_answer = "correct_ans"),
   correct := 1L ] 

    student question_id student_answer correct
 1:       b           1              2       1
 2:       c           1              4       1
 3:       b           1              1       0
 4:       b           2              3       0
 5:       c           2              2       1
 6:       b           2              4       1
 7:       c           3              4       1
 8:       b           3              5       0
 9:       a           4              2       0
10:       c           4              1       1

工作原理。更新联接的语法是X[Y, on=cols, xvar := z]

  • 如果列表名称在XY之间有所不同,请使用on=c(xcol = "ycol", xcol2 = "ycol2")或版本1.9.7 +,.(xcol = ycol, xcol2 = ycol2)
  • xvar := z仅适用于匹配的X行。有时,在此处使用by=.EACHI也很有用,具体取决于X中每个Y的匹配行数以及z的表达式复杂程度。< / LI>

有关语法的完整文档,请参阅?data.table