我有由不同测试题(例如Q1、Q2、Q3)的答案组成的列,我想编写一个函数来评估这些答案,并用每个测试题(1或0)的分数创建新的列,其中'id‘表示不同的个体。
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',如果答案等于' answers‘中的第一个值,则返回1 else 0”……然后“对于第二个问题'Q2',如果答案等于第二个值...”,等等。
answers=c(4,6,8)
newcols=paste('Q',rep(1:3),'_score',sep='')
dt[,(newcols):= function, id, .SDcols=2:4]发布于 2017-01-30 20:47:51
我们使用除第一列之外的所有列指定列,使用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发布于 2017-01-30 20:48:04
从开始
> 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您希望将Q列提取到一个矩阵中,然后通过转置、按列比较(因为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 0https://stackoverflow.com/questions/41936175
复制相似问题