2017-01-30 7 views
2

У меня есть столбцы, состоящие из ответов на различные тестовые вопросы (например, Q1, Q2, Q3), и я хотел бы написать функцию, которая оценивала бы эти ответы и создавать новые столбцы с оценками для каждого тестового вопроса (1 или 0), где «id» относится к разным людям.Функция R для оценки значений в столбцах data.table против другого набора значений

id Q1 Q2 Q3 
    1 4 3 3 
    2 7 3 7 
    3 8 5 6 
    4 8 2 8 
    5 4 6 8 
    6 4 6 6 
    7 4 6 5 
    8 4 6 8 
    9 4 6 6 

Выход Я ищу это

id Q1 Q2 Q3 Q1_score Q2_score Q3_score 
    1 4 3 3  1  0  0 
    2 7 3 7  0  0  0 
    3 8 5 6  0  0  0 
    4 8 2 8  0  0  1 
    5 4 6 8  1  1  1 
    6 4 6 6  1  1  0 
    7 4 6 5  1  1  0 
    8 4 6 8  1  1  1 
    9 4 6 6  1  1  0 

Я определил правильные ответы и новые имена столбцов ниже, но я не могу показаться, чтобы выяснить функцию, которая будет делать что-то вроде «для первого вопроса« Q1 », если ответ равен первому значению в« ответах », верните 1 else 0« ... then »для второго вопроса« Q2 », если ответ равен второе значение ... »и т. д.

answers=c(4,6,8) 
newcols=paste('Q',rep(1:3),'_score',sep='') 
dt[,(newcols):= function, id, .SDcols=2:4] 
+3

Я боюсь, что мой 'data.table' знание бедно, но вы могли бы сделать это с' mapply() 'в базе R. Будет что-то вроде' DT [, newcols] < - mapply (функция (x, y) ifelse (x == y, 1, 0), dt [2: 4], ответы) ' – LAP

ответ

2

Мы указываем .SDcols со всеми столбцами, кроме первого, используйте Map для сравнения соответствующего элемента list (т. столбец) с соответствующим значением в answers, преобразовать его в integer и назначить (:=) к новым колонкам с помощью paste

library(data.table) 
dt[, paste0(names(dt)[-1], "_score") := 
     Map(function(x,y) as.integer(x==y), .SD, answers), .SDcols = -1] 
dt 
# id Q1 Q2 Q3 Q1_score Q2_score Q3_score 
#1: 1 4 3 3  1  0  0 
#2: 2 7 3 7  0  0  0 
#3: 3 8 5 6  0  0  0 
#4: 4 8 2 8  0  0  1 
#5: 5 4 6 8  1  1  1 
#6: 6 4 6 6  1  1  0 
#7: 7 4 6 5  1  1  0 
#8: 8 4 6 8  1  1  1 
#9: 9 4 6 6  1  1  0 
2

Начиная с

> quiz 
    id Q1 Q2 Q3 
1 1 4 3 3 
2 2 7 3 7 
3 3 8 5 6 
4 4 8 2 8 
5 5 4 6 8 
6 6 4 6 6 
7 7 4 6 5 
8 8 4 6 8 
9 9 4 6 6 

Вы хотите извлечь из добротность столбцов в матрице а затем выполняйте сравнение по строкам путем транспонирования, сравнивая по столбцу (потому что R хранит матрицы в порядке столбцов), а затем переносит обратно.

Затем вы можете преобразовать в числовое число, добавив 0, исправить имена с помощью быстрого paste0, а затем cbind на ваш оригинал. Вот решение:

> resp = t(t(quiz[,2:4]) == c(4,6,8))+0 
> colnames(resp)=paste0(colnames(resp),"_score") 
> cbind(quiz, data.frame(resp)) 
    id Q1 Q2 Q3 Q1_score Q2_score Q3_score 
1 1 4 3 3  1  0  0 
2 2 7 3 7  0  0  0 
3 3 8 5 6  0  0  0 
4 4 8 2 8  0  0  1 
5 5 4 6 8  1  1  1 
6 6 4 6 6  1  1  0 
7 7 4 6 5  1  1  0 
8 8 4 6 8  1  1  1 
9 9 4 6 6  1  1  0