我正在尝试编写成绩计算功能。该功能应该是:
我已经写了以下代码:
grades = read.table('http://pengstats.macssa.com/download/rcc/grades.csv',
header=T, sep=',', fill=TRUE)
grade_cal = function (graded, hw_w, quiz_w, exam_w){
if(!is.matrix(grades) & !is.data.frame(grades)){
stop('Grades must be in a data frame or a matrix.')
}
grades[is.na(grades)] = 0;
grades$Final=100*hw_w*rowSums(grades[,3:10])/(5*8)+
100*quiz_w*rowSums(grades[,11:15])/(10*5)+
100*exam_w*3*rowSums(grades[,16:18])/(100*3)
grades$Letter = {
if (grades$Final >=90) {
grade = "A"
}
else if (grades$Final >=80){
grade = "B"
}
else if(grades$Final >=70){
grade = "C"
}
else if(grades$Final >=60){
grade = "D"
}
else {grade = "F"}
}
message("There are 8 HWs, 4 Quizzes and 3 Exams Calculated for each person.")
message("Weights are", hw_w, ",", quiz_w, ",", exam_w, "respectively for HW, Quiz and Exam.")
grades[1:3,]
}
grade_cal(graded= grades, 0.2, 0.2, 0.2)
此代码目前返回以下"错误[.data.frame
(成绩,最终):对象'最终'找不到"。当我删除该部分以尝试计算字母等级时,我的代码运行,这就是错误所在的位置(我只包含其余代码以提供一些背景信息)。如何修复字母计算部分以使其运行?感谢
编辑:将成绩[最终]更改为等级$ Final后,我现在收到以下警告:" In if(grade $ Final> = 90){: 条件的长度> 1,只使用第一个元素"
答案 0 :(得分:2)
只需将您的grades$Letter
来电替换为
grades$Letter = cut(grades$Final,
breaks = c(0,60,70,80,90, 100),
labels = c("F", "D", "E", "B", "A"),
right = FALSE,
include.lowest = TRUE)
哪个给你
Session UserID HW1 HW2 HW3 HW4 HW5 HW6 HW7 HW8 Q1 Q2 Q3 Q4 Q5 Exam1 Exam2 Exam3 Final Letter
1 A 1 5.0 5.0 5.0 4.8 5 4.8 4.9 5 10 10 9 7.0 10 90.5 92.5 90.5 92.85 A
2 A 2 4.8 4.9 4.6 5.0 5 4.6 5.0 5 10 7 6 7.5 9 63.0 45.5 37.0 64.35 D
3 A 3 4.8 4.9 4.4 0.0 0 0.0 4.9 5 8 7 5 0.0 9 0.0 0.0 0.0 23.60 F
如果您想使用if ... else
结构,可以使用为此类任务进行矢量化的ifelse
答案 1 :(得分:0)
正如@Haboryme指出的那样,if else
在你使用它时只适用于单个值,而不适用于矢量。坚持使用if-else逻辑的(相当繁琐)的要求,这可能会这样做:
grades$Letter = ifelse(grades$Final >=90, "A",
ifelse(grades$Final >=80, "B",
ifelse(grades$Final >=70, "C",
ifelse(grades$Final >=60, "D", "F"))))
或者,您可以编写for
循环(作为错误,错误编码的示例):
grades$Letter = ""
for (i in seq_along(grades$Final)) {
print(grades$Final[i])
grades$Letter[i] = {
if (grades$Final[i] >=90) {
"A"
}
else if (grades$Final[i] >=80){
"B"
}
else if(grades$Final[i] >=70){
"C"
}
else if(grades$Final[i] >=60){
"D"
}
else {"F"}
}
}
这第二个选项特别糟糕,因为它可以让你在了解正在发生的事情之前阅读了很多代码,并且因为已经有一些很好的矢量化解决方案已经在这个线程中的其他人已经指出。