为向量中的段创建一个循环,为每个相应的段提供 return 值

Creating a loop for segments within a vector that give return values for each corresponding segment

我创建了一个包含 100 个随机数的向量 "numGrades" 来表示评分系统中的值。我需要编写一个 "for" 循环,它采用数字等级段和 returns 相应字母等级的向量,即:90+ = "A", 80-89 = "B", 70-79 = "C"、60-69 = "D"、0-59 = "F"。我希望能够将 运行 numGrades 转为 return 对应的字母等级 例如:numGrades = [72, 65, 93] returning = ["C", "D", "A"] 循环处理任意长度的向量。 这是我到目前为止单独尝试过的方法。所有这些循环都有 returned 警告:

set.seed(43)
numGrades <- sample(0:100, 100, replace=FALSE)

for (i in numGrades )
  if(91 <= numGrades[i]) {
    numGrades[i] <- "A"
  } else if (80 <= numGrades[i] & numGrades[i] <= 90) {
    numGrades[i] =="B"
  } else if (70 <= numGrades[i] & numGrades[i] <= 79) {
    numGrades[i] =="C"
  } else if (60 <= numGrades[i] & numGrades[i] <= 69) {
    numGrades[i] =="D"
  } else if (0 <= numGrades[i] & numGrades[i] <= 59) {
    numGrades[i] =="F"
  }

它在说:

Error in if (91 <= numGrades[i]) { : 
  missing value where TRUE/FALSE needed

新编辑(Returns 仅限成绩 >= 91):

numGrades <- (0:100)
for (i in 1:length(numGrades ))
  if(91 <= numGrades[i]) {
    numGrades[i] <- "A"
  } else if (80 <= numGrades[i] & numGrades[i] <= 90) {
    numGrades[i] =="B"
  } else if (70 <= numGrades[i] & numGrades[i] <= 79) {
    numGrades[i] =="C"
  } else if (60 <= numGrades[i] & numGrades[i] <= 69) {
    numGrades[i] =="D"
  } else if (0 <= numGrades[i] & numGrades[i] <= 59) {
    numGrades[i] =="F"
  }

工作草稿

ltrGrades <- (0:100)
numGrades <- character(length(ltrGrades))

for (i in 1:length(ltrGrades ))
  if(any(ltrGrades[i] == 91:100)) {
    numGrades[i] <- "A"
  } else if (any(ltrGrades[i] == 80:90)) {
    numGrades[i] <- "B"
  } else if (any(ltrGrades[i] == 70:79)) {
    numGrades[i] <- "C"
  } else if (any(ltrGrades[i] == 60:69)) {
    numGrades[i] <- "D"
  } else if (any(ltrGrades[i] == 0:59)) {
    numGrades[i] <- "F"
  }

您的代码存在一些基本的 R 语法问题。

(numGrades[i]) c(80:90))
(numGrades[i]) >=80 && <=89)
(numGrades[i]) ==80:89 )

几种选择,效率最低:

(80 <= numGrades[i] & numGrades[i] < 90)    # the most basic
(dplyr::between(numGrades[i], 80, 90))      # if dplyr is loaded
(data.table::between(numGrades[i], 80, 90)) # if data.table is available
(numGrades[i] %in% 80:89)                   # works only if all grades are perfectly integral
(any(numGrades[i] == 80:89))                # ditto

他们为什么错了?

  • (numGrades[i]) c(80:90)),因为没有operator
  • (numGrades[i]) >=80 && <=89),R 不会像您建议的那样推断它们,每次进行(不)等式测试时,您都需要为每个测试指定 LHS 和 RHS;同样,不太可能有很多语言,R 不会 "chain" 它们,所以 (80 <= numGrades[i] <= 89) 将不起作用
  • (numGrades[i]) ==80:89 )越来越近了,但是if/else语句需要单比;在这种情况下,您正在将一个数字与 10 的序列(范围)进行比较,因此此回复的长度为 10。它的长度必须为 1。

不过,底线是您不需要循环。

# set.seed(43)
numGrades <- sample(0:100, 100, replace=FALSE)
cut(numGrades, c(-1, 60, 70, 80, 90, 101), labels=c("F","D","C","B","A"))
#   [1] F A F D F F D F F C F F F F F B F A F F C A F F F F A F A F C C C B F
#  [36] F F F B A F F F A B B C D F F F B D F F B D D B F F F F F F D F A F F
#  [71] F F F F B F D F A F F F F F A B F F F C F F F D D C C F F F
# Levels: F D C B A

或者如果您不喜欢或不理解 factor 是什么,那么

as.character(cut(numGrades, c(-1, 60, 70, 80, 90, 101), labels=c("F","D","C","B","A")))
#   [1] "F" "A" "F" "D" "F" "F" "D" "F" "F" "C" "F" "F" "F" "F" "F" "B" "F"
#  [18] "A" "F" "F" "C" "A" "F" "F" "F" "F" "A" "F" "A" "F" "C" "C" "C" "B"
#  [35] "F" "F" "F" "F" "B" "A" "F" "F" "F" "A" "B" "B" "C" "D" "F" "F" "F"
#  [52] "B" "D" "F" "F" "B" "D" "D" "B" "F" "F" "F" "F" "F" "F" "D" "F" "A"
#  [69] "F" "F" "F" "F" "F" "F" "B" "F" "D" "F" "A" "F" "F" "F" "F" "F" "A"
#  [86] "B" "F" "F" "F" "C" "F" "F" "F" "D" "D" "C" "C" "F" "F" "F"

编辑

我刚注意到您的代码还有其他问题。

开始时,numGrades 是数字或整数。但是,由于它是一个向量,因此第一次将字母分配给其中一个元素时,整个向量将转换为 character 向量。第二次通过 for 循环将尝试将数字与字符串进行比较,这不会进行数字比较,尝试 8 < "75" 为什么会失败。

解决此问题的方法:

ltrGrades <- character(length(numGrades))
for (i in 1:length(numGrades ))
  if(91 <= numGrades[i]) {
    ltrGrades[i] <- "A"
  } else if (80 <= numGrades[i] & numGrades[i] <= 90) {
    ltrGrades[i] <- "B"
  } else if (70 <= numGrades[i] & numGrades[i] <= 79) {
    ltrGrades[i] <- "C"
  } else if (60 <= numGrades[i] & numGrades[i] <= 69) {
    ltrGrades[i] <- "D"
  } else if (0 <= numGrades[i] & numGrades[i] <= 59) {
    ltrGrades[i] <- "F"
  }