簡體   English   中英

如何在 r 中找到加權平均值?

[英]How do I find weighted average in r?

我想計算您課程中的學生成績。 我想出了需要完成的步驟,但一直無法完成。

  • 創建一個名為“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 中有很多方法可以做到這一點,但這里有一個簡單的方法,只使用向量:

我使用的技巧是用另一個向量索引一個向量,以便將每個等級與權重相匹配。 首先,我提取了您的示例數據:

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

要計算算術平均值,我們需要能夠同時使用分數和權重進行編程。 要做到這一點,我第一次創造了他們之間的映射使用基於快速編碼方案每級別的命名載體

> 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.frame s,但基於vector的方法在這里似乎運行良好。

我一直喜歡做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

你的意思是像下面這樣嗎?

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
)

您可以使用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的開頭,這些assignments用於match wgt的名稱。

我的解決方案可能有點冗長,但通過使用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
            )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM