Табулирование школьных оценок с помощью data.table (длинная форма в широкую форму)

#r #data.table

#r #data.table

Вопрос:

У меня есть большая база данных курсов с оценкой и идентификатором студента. Это выглядит примерно так (со многими другими переменными, которые были удалены для упрощения):

 studentID    course       grade
--------------------------------
1            chemistry    86
2            chemistry    85
2            math         72
3            english      52
3            math         90
...
  

Мне нужно преобразовать этот большой файл в файл, в котором у каждого учащегося есть своя строка с оценками для всех разных курсов. Что-то вроде этого:

 studentID    chemistry    math    english
----------------------------------------
1            86           NA      NA
2            85           72      NA
3            NA           90      52
  

Вот код для создания моей базы данных sampler:

 course.db <- data.table(
              studentID=c("1", "2", "2", "3", "3"),
              course=c("chemistry", "chemistry", "math", "english", "math"),
              grade=c(86, 85, 72, 52, 90)
           )
  

Обычно я создаю базу данных файлов учащихся с обычной информацией (средний балл, школа и т. Д.) Следующим образом:

 student.files <- course.db[, .(
    average=mean(grade, na.rm=T) #more vars are created here
), by="studentID"]
  

Затем я создаю другую таблицу с нужной мне оценкой:

 math.grades <- course.db[course=="math", .(
    math=grade
), by="studentID"]
  

Затем я объединяю все это. Это работает, когда есть только несколько курсов, по которым можно получить оценку. Но мне нужно собрать оценки как минимум из дюжины курсов. Итак, мой вопрос: как я могу условно оценивать оценку в зависимости от значения столбца «оценка»?Что я ищу:

 #careful: not working code
student.files <- course.db[, .(
    average = mean(grade, na.rm=T) #more vars are created here,
    math = ThenAMiracleOccurs("math", grade),
    english = ThenAMiracleOccurs("english", grade),
    chemistry = ThenAMiracleOccurs("chemistry", grade),
), by="studentID"]
  

Ответ №1:

Спасибо, Хьюберт. Я не заметил, что существует версия data.table (моя БД довольно большая, поэтому мне нужно по возможности оставаться в мире data.table). Вот рабочее решение, использующее dcast для data.table:

 dcast.data.table(course.db, studentID~course, value.var="grade" )
  

Отмечено из комментария: простой dcast также будет работать и использовать метод data.table, если таблица уже является объектом data.table:

 dcast(course.db, studentID~course, value.var="grade" )
  

Результат:

    studentID chemistry english math
1:         1        86      NA   NA
2:         2        85      NA   72
3:         3        NA      52   90
  

Комментарии:

1. Последние версии data.table не требуют вызова dcast.data.table , пока уже course.db есть a data.table , вы можете просто использовать dcast .