【发布时间】:2017-05-26 16:52:47
【问题描述】:
我有一个数据框,其中包含由多个编码员生成的一组项目评级。并非所有编码员都对所有项目进行排名。对于每个项目,我想根据前两名编码员的评分生成一个平均值,如外部排名系统所示。编码员的排名从 A(最高)到 D(最低)。在我当前的代码中,我按编码器排名(从 A 到 D)对列进行排序,然后使用 for 循环:
CoderA CoderB CoderC CoderD
1 2 1 NA 1
2 1 3 3 NA
3 NA NA 4 5
4 7 6 7 6
5 3 3 4 2
6 2 2 NA NA
7 2 NA 2 1
8 5 3 NA 4
9 7 7 6 NA
10 1 NA 3 4
df <- data.frame(
CoderA = c(2,1,NA,7,3,2,2,5,7,1),
CoderB = c(1,3,NA,6,3,2,NA,3,7,NA),
CoderC = c(NA,3,4,7,4,NA,2,NA,6,3),
CoderD = c(1,NA,5,6,2,NA,1,4,NA,4))
df$first_sc <- apply(df, 1, function(x) names(df[which(!is.na(x))])[1])
df$sec_sc <- apply(df, 1, function(x) names(df[which(!is.na(x))])[2])
for (x in seq(1,nrow(df))) {
first_rating <- df[x,df$first_sc[x]]
second_rating <- df[x,df$sec_sc[x]]
df$BestAvg[x] <- (first_rating + second_rating) / 2
}
问题 1:对于上述简单案例的更简洁的解决方案有什么建议吗? (for 循环不是首选,但我在类似的应用函数中被困在索引上。)
问题 2: 在第二个数据帧中,列不按编码器排名排序(例如,列按 'CoderD'、'CoderB'、'CoderC'、 '编码器')。考虑到这种约束,我该如何解决同样的问题?
【问题讨论】:
-
对于第一个问题,您可以使用
apply(df,1,function(x) mean(x[!is.na(x)][1:2]))。不确定我是否理解第二个问题,您不能事先对列重新排序吗? -
您的建议是问题 1 的一个很好的解决方案;谢谢!问题 2 适用于更动态的情况。在我的完整脚本中,编码员的外部排名会根据其他数据进行调整,并且可以从脚本的一部分更改为另一部分。我不想在每次排名发生变化时重新排序列,因此寻求可以直接指定列排名的替代方案。