2017-10-03 7 views
2

データの操作方法を理解しようとしていますhere。画像には1つのコースしか表示されませんが、2010年から2017年までの複数のコースとコース番号があります。年、教え、用語に基づいて特定のコースのメジアンの等級を示す列を追加するにはどうすればよいですか?私たちには、ある成績ではなく、実際の成績ではない子供の数があります。私は、それぞれの "教えられた"変数に基づいて、11の異なる等級について中央値の等級欄が11の重複であることを期待しています。指導者は、「ここ」または「そこ」の2つの値しか持てません。2列からRに暗黙的に中間値を取得

私は集約関数を使用しようとしましたが、この問題は高水準関数で解決できるもののようには見えません。 dbはRのDBKidsです。私はこの問題で私を助けることができる方法を考えることができません。ありがとう!

編集:再現コード

structure(list(sessionYear = c(2010, 2010, 2010, 2010, 2010, 
2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 
2010, 2010, 2010, 2010, 2010, 2010), courseNumber = c("20", "20", 
"20", "20", "20", "20", "20", "20", "20", "20", "20", "20", "20", 
"20", "20", "20", "20", "20", "20", "20", "20", "20"), 
courseName = c("KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", 
"KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", 
"KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", 
"KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", "KidsLearn", 
"KidsLearn", "KidsLearn", "KidsLearn"), Taught = c("There", 
"Here", "There", "Here", "There", "Here", "There", 
"Here", "There", "Here", "There", "Here", "There", 
"Here", "There", "Here", "There", "Here", "There", 
"Here", "There", "Here"), Term = c("1", "1", "1", "1", "1", 
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
"1", "1", "1", "1"), averageGrade = c(83, 84, 83, 84, 83, 84, 
83, 84, 83, 84, 83, 84, 83, 84, 83, 84, 83, 84, 83, 84, 83, 84 
), Grade = c("F", "F", "D", "D", "C3", "C3", "C2", "C2", "C1", 
"C1", "B3", "B3", "B2", "B2", "B1", "B1", "A3", "A3", "A2", "A2", 
"A1", "A1"), numberOfKids = c(1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 
3, 0, 3, 2, 6, 0, 14, 7, 24, 4, 18, 4)), class = "data.frame", row.names = c(NA, 
-22L), .Names = c("sessionYear", "courseNumber", "courseName", 
"Taught", "Term", "averageGrade", "Grade", "numberOfKids")) 

は、この情報がお役に立てば幸いです。

+0

R-FAQ [グループで平均を計算する方法](https://stackoverflow.com/q/11562656/903061)から好きなグループ/集計メソッドを選んで実行しますが、 'mean'を' weighted .median'を 'spatstat'パッケージから削除します。 (またはそれを実装する他のパッケージ(https://www.rdocumentation.org/search?q=weighted.median&latest=1))。 factor級のレベルを 'as.integer'で整数に変換する必要があります(レベルが正しく揃っていることを確認してください) – Gregor

+1

[再現可能な例]を提供すると助けが簡単です(https://stackoverflow.com)。/questions/5963269/how-to-make-a-great-r-reproducible-example)を参照してください。データの画像はそれほど有用ではありません。 'dput()'を試してみるか、データセットに組み込まれたサンプルを使って問題を説明してください。希望する出力を与えます。 – MrFlick

+0

私はコードを追加しました。提案していただきありがとうございます! –

答えて

0

まず、レベルが正しい順序であることを確認して、グレードのfactorを作成します。これは数値に変換して、中央値を取る数値を持つことができます。

levels(factor(dd$Grade)) 
# [1] "A1" "A2" "A3" "B1" "B2" "B3" "C1" "C2" "C3" "D" "F" 

## order seems good 

dd$grade_numeric = as.numeric(factor(dd$Grade)) 

は、今、私たちは、子供の数、最も近い整数に丸めることにより、加重グループによる中央値を、やると手紙グレードに戻って変換します。

library(dplyr) 
group_by(dd, sessionYear, Taught, Term) %>% 
    mutate(med = spatstat::weighted.median(x = grade_numeric, w = numberOfKids), 
      med = round(med), 
      median_Grade = levels(factor(Grade))[med]) %>% 
    print.data.frame 
# sessionYear courseNumber courseName Taught Term averageGrade Grade numberOfKids grade_numeric med median_Grade 
# 1   2010   20 KidsLearn There 1   83  F   1   11 2   A2 
# 2   2010   20 KidsLearn Here 1   84  F   0   11 2   A2 
# 3   2010   20 KidsLearn There 1   83  D   0   10 2   A2 
# 4   2010   20 KidsLearn Here 1   84  D   0   10 2   A2 
# 5   2010   20 KidsLearn There 1   83 C3   1    9 2   A2 
# 6   2010   20 KidsLearn Here 1   84 C3   0    9 2   A2 
# 7   2010   20 KidsLearn There 1   83 C2   1    8 2   A2 
# 8   2010   20 KidsLearn Here 1   84 C2   0    8 2   A2 
# 9   2010   20 KidsLearn There 1   83 C1   0    7 2   A2 
# 10  2010   20 KidsLearn Here 1   84 C1   0    7 2   A2 
# 11  2010   20 KidsLearn There 1   83 B3   3    6 2   A2 
# 12  2010   20 KidsLearn Here 1   84 B3   0    6 2   A2 
# 13  2010   20 KidsLearn There 1   83 B2   3    5 2   A2 
# 14  2010   20 KidsLearn Here 1   84 B2   2    5 2   A2 
# 15  2010   20 KidsLearn There 1   83 B1   6    4 2   A2 
# 16  2010   20 KidsLearn Here 1   84 B1   0    4 2   A2 
# 17  2010   20 KidsLearn There 1   83 A3   14    3 2   A2 
# 18  2010   20 KidsLearn Here 1   84 A3   7    3 2   A2 
# 19  2010   20 KidsLearn There 1   83 A2   24    2 2   A2 
# 20  2010   20 KidsLearn Here 1   84 A2   4    2 2   A2 
# 21  2010   20 KidsLearn There 1   83 A1   18    1 2   A2 
# 22  2010   20 KidsLearn Here 1   84 A1   4    1 2   A2 

は、この例では唯一の2グループ(期間および年は一つの値だけ、それぞれを持っている)があり、それらの両方は、A2の中央値はグレードがあります。 (右にスクロールすると、追加された列が表示されます)

1

したがって、各エントリ番号は、グレードで対応するグレードを取得した子供の数ですか? 、あなたは2つの値の平均を取る「ネクタイ」があります場合は、中央値で通常

get_median = function(numberOfKids,Grade){ 
current_count = 0 
middle = (sum(numberOfKids)+1)/2 
for (i in 1:length(numberOfKids)){ 
    current_count = current_count+numberOfKids 
    #if we're halfway through the class, return the current grade 
    if (current_count == middle) return(Grade[i]) 
    #if we're more than halfway through the class, then decide whether 
    #the middle is closer to the current total or the previous 
    if (current_count > middle){ 
    if ((current_count-middle) > numberOfKids[i]/2) return(Grade[i]) 
    return(Grade[i-1] } } } 

を行うことで、「手で」中央値を得ることができますが、実際には2つの平均を取ることができませんあなたが選ぶものを決める必要があります。この機能では、完全なタイがある場合、それはより低いグレードを取る。最後の ">"を "> ="に変更することで変更できます。

+0

'cumsum'と' findInterval'ではやや簡単な方法があります。ニースのアプローチ! – Gregor

関連する問題