[英]How do I use condition with rows in a dataframe (weighted average, R language)?
[英]How do I find weighted average in r?
我想計算您課程中的學生成績。 我想出了需要完成的步驟,但一直無法完成。
到目前為止,我有向量
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.