【问题标题】:ifelse assignment in data.tabledata.table 中的 ifelse 赋值
【发布时间】:2017-03-11 21:44:34
【问题描述】:

我是一名教师,想正确使用R 中的data.table 包在日志文件中自动为学生的答案评分,即如果学生回答特定问题,则添加一个名为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))

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

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

我考虑用joining 和question_tablelog 表中使用正确的ans 创建一个帮助列,但这不起作用,因为后者的键不是唯一的。

我们将不胜感激。 提前致谢。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您可以使用连接:

    # 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 也很有用,这取决于XY 中每个匹配的行数以及z 的表达式有多复杂。

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2020-04-20
    • 2016-10-13
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多