【问题标题】:How do I find weighted average in r?如何在 r 中找到加权平均值?
【发布时间】:2019-12-19 07:22:04
【问题描述】:

我想计算学生在您的课程中的成绩。我想出了需要完成的步骤,但我一直无法完成。

  • 创建一个名为“report_card”的向量,按此顺序包含 92、88、91、97、85。
  • 使用作业名称创建另一个名为“assignments”的向量,顺序为 HW1、Exam 1、Quiz、Exam 2、HW2
  • 使用“作业”为“report_card”成绩分配名称
  • 如果考试占成绩的 50%,测验占 30%,作业占 20%,则计算学生在课堂上的成绩。将答案分配给“student_grade”

到目前为止我有向量

report_card <- c(92,88,91,97,85)
assignments <- c("HW1", "Exam 1", "Quiz", "Exam 2", "HW2")

我不知道如何链接它们或从那里去哪里。有什么建议吗?

【问题讨论】:

    标签: r vector average


    【解决方案1】:

    好问题!在 R 中有很多方法可以做到这一点,但这里有一个只使用向量的简单方法:

    我使用的技巧是用另一个向量索引一个向量,以便将每个等级与一个权重相匹配。首先,我提取了您的示例数据:

    > assignments <- c("HW1", "Exam 1", "Quiz", "Exam 2", "HW2")
    > report_card <- c(92, 88, 91, 97, 85)
    

    要计算算术平均值,我们需要能够同时使用分数和权重进行编程。为此,我首先使用 named vector 创建了它们之间的映射,该映射基于每个等级的 type 的快速编码方案:

    > weights <- c("H"=20, "Q"=30, "E"=50)
    > assignment_types <- c("H", "E", "Q", "E", "H")
    

    这让我们可以通过索引一个向量与另一个向量来找到每个分配应获得的绝对权重:

    > weights[assignment_types]
     H  E  Q  E  H 
    20 50 30 50 20 
    

    了解 R 如何将 weights 命名向量的名称与 assignment_types 向量中的值匹配?

    现在我们有办法获得每个作业的权重,我们可以计算加权成绩,如下所示:

    > (student_grade <- sum(report_card * weights[assignment_types]) / sum(weights[assignment_types]))
    [1] 91.29412
    

    因为这是 R,所以有很多方法可以做到这一点。更整洁的方法可能会使用 data.frames,但基于 vector 的方法似乎在这里运行良好。

    【讨论】:

      【解决方案2】:

      我一直喜欢做dplyr 版本。

      library(dplyr)
      
      report_card <- c(92,88,91,97,85)
      assignments <- c("HW1", "Exam 1", "Quiz", "Exam 2", "HW2")
      
      # get rid of the numbers here (and the whitespaces)
      assignments <- gsub("[[:digit:]]", "", assignments)
      assignments <- gsub(" ", "", assignments)
      
      assignment_weights <- data.frame(assignments = c("HW", "Exam", "Quiz")
                                       , weights = c(0.2, 0.5, 0.3))
      
      # now put both into a dataframe
      df <- data.frame(report_card, assignments)
      
      # now take this dataframe and...
      df %>%
          group_by(assignments) %>% # for every assignment type
          summarise(avgGrade_byAssignmentType = mean(report_card)) %>% # you calculate the average...
          left_join(assignment_weights, by = "assignments") %>% # now you add the weights
          summarise(finalGrade = weighted.mean(avgGrade_byAssignmentType, weights)) # and calculate a weighted average
      

      【讨论】:

        【解决方案3】:

        你的意思是像下面这样的吗?

        ws <- sum(sapply(c("HW","Quiz","Exam"), function(x) mean(report_card[grepl(x,names(report_card))]))*c(0.2,0.3,0.5))
        

        ws <- (c(0.2,0.3,0.5)%*%sapply(c("HW","Quiz","Exam"), function(x) mean(report_card[grepl(x,names(report_card))])))[1]
        

        这样

        > ws
        [1] 91.25
        

        数据

        report_card <- c(HW1 = 92, `Exam 1` = 88, Quiz = 91, `Exam 2` = 97, HW2 = 85
        )
        

        【讨论】:

          【解决方案4】:

          您可以使用weighted.mean计算加权平均值

          wgt  <- c(HW=20, Quiz=30, Exam=50)
          weighted.mean(report_card, 
           wgt[match(gsub("^([[:alpha:]]+).*","\\1",assignments), names(wgt))])
          #[1] 91.29412
          

          使用wgt 定义权重。对于gsub,只取assignments 的开头,而那些用于matchwgt 的名称。

          【讨论】:

            【解决方案5】:

            我的解决方案可能有点冗长,但通过使用 data.frame 和一些 dplyr 逻辑,我们可以轻松构建一个可读且可重复的管道,以便在多个学生上运行此分析。

            假设我们创建一个可以包含多个学生的data.frame

            student <- rep("john doe", 5)
            report_card <- c(92,88,91,97,85)
            assignments <- c("HW1", "Exam 1", "Quiz", "Exam 2", "HW2")
            
            data <- data.frame(student, report_card, assignments)
            

            然后,我们将首先为每个分配分配一个标准化变量。通过按学生和这个标准化变量分组,我们可以计算每个学生每种类型作业的平均分数。

            然后通过第二次summarise 对每种作业类型的加权平均分数求和,即可轻松计算总成绩。

            data %>% 
              mutate(assignment_standardized  = case_when(
                grepl("Exam", assignments) ~ "E",
                grepl("Quiz", assignments) ~ "Q",
                grepl("HW", assignments) ~ "H",
                TRUE ~ ""
              )) %>% 
              group_by(student, assignment_standardized) %>% 
              summarise(report_normalized  = mean(report_card)) %>% 
              summarise(student_grade = 
                          report_normalized[assignment_normalized == "E"] * 0.5 + 
                          report_normalized[assignment_normalized == "Q"] * 0.3 +
                          report_normalized[assignment_normalized == "H"] * 0.2
                        )
            

            【讨论】:

              猜你喜欢
              • 2012-06-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-28
              • 1970-01-01
              • 1970-01-01
              • 2018-02-24
              • 1970-01-01
              相关资源
              最近更新 更多