単純に順位を付ける場合は『RANK関数』を使いますが、『COUNTIFS関数』を使うと『グループ別』や『対象を限定』等の条件が付いた順位を計算することが出来ます。
- 例:20歳未満を対象に、AとBのグループ別に順位を付ける
D2のセルの式は次の通りです。式の解説は後で詳しく行います。
=IF(B2<20,COUNTIFS(A$2:A$7,A2,$B$2:$B$7,"<20",C$2:C$7,">"&C2)+1,"対象外")
注意:『COUNTIFS関数』が使えるのは『Excel2007』以降です。
それ以前のバージョンでは『SUMPRODUCT関数』を使いますが、2007以降であれば『COUNTIFS関数』のほうが計算速度が速いのでおすすめです。
以降で、詳しいやり方を説明します。
目次
COUNTIFS関数について
『COUNTIFS関数』は順位付け専用の関数ではありません。『複数(1つでも可)の条件に一致した行数(または列数)を数える』関数です。
例えば『A列の値が1かつB列の値が2の行が何行あるか数える』ことが出来ます。
使い方は次のとおりです。
=COUNTIFS(範囲1,検索条件1,[範囲2,検索条件2,…]) ※[]内は省略可能
COUNTIFS関数の検索条件の書き方
『検索条件』の書き方が少し変わってるので説明します。
- 比較演算子(>,<,>=,<=,=,<>)と比較する値を『"(ダブルコーテーション)』で囲む
用例 意味 =COUNTIFS($A$2:$A$7,">=20") A2~A7で値が20以上のセルの数 =COUNTIFS($A$2:$A$7,"<>はてな") A2~A7で値が"はてな"ではないセルの数 - 『=(イコール)』は省略可
- 数値は『"(ダブルコーテーション)』も省略可
=COUNTIFS($A$2:$A$7,"はてな") A2~A7で値が"はてな"のセルの数 =COUNTIFS($A$2:$A$7,20) A2~A7で値が20に等しいセルの数 - 数値は『"(ダブルコーテーション)』も省略可
- セルは『"(ダブルコーテーション)』で囲まない
- 比較演算子とセルは『&(アンド)』でつなげる
=COUNTIFS($A$2:$A$7,A2) A2~A7で値が20に等しいセルの数 =COUNTIFS($A$2:$A$7,">"&A2) A2~A7で値がA2の値より大きいセルの数 - 比較演算子とセルは『&(アンド)』でつなげる
順位付けの仕組み
順位(降順)は、言い換えると『"自分よりポイントの高い人"の数に1を足したもの』です。
1位は、『自分よりポイントが高い人が0人』+1で、1位
2位は、『自分よりポイントが高い人が1人』+1で、2位
といった感じです。
つまり『自分よりポイントが高い人』を『COUNTIFS関数』で数えて1を足すことで順位が計算出来ます。
順位付けの手順
まずは条件のない単純な順位付けを行います。
次の表に順位を付けます。
- 下記の表全体を選択して右クリック→『コピー』をクリックします。
ポイント 順位 80 65 90 85 70 75 - ExcelのシートでA1のセルを右クリック→『形式を選択して貼り付け』をクリックします。
- 『貼り付ける形式』で『テキスト』を選択して『OK』をクリックします。
- B2のセルに『=countifs』と入力して、キーボードの『TAB』押します。
- A2~A7セルをドラッグして選択して、キーボードの『F4』を1回押します。
*『F4』を押す度に『$A$2(列行固定)』→『A$2(行固定)』→『$A2(列固定)』→『A2(固定なし)』と循環します。固定すると式をコピーした時に勝手にセルの位置が変更されません。
- 続けて『,">"&A2)+1』を入力して、キーボードの『Enter』を押します。
最終的に下記の式になります。=COUNTIFS($A$2:$A$7,">"&A2)+1
- B2のセルの枠の右下をドラッグして、B3~B7のセルにコピーします。
グループ別の順位を付ける
グループ別に順位を付ける場合は、『グループが自分と同じ人』という条件を追加します。
『自分よりポイントが高い人』かつ『グループが自分と同じ人』を『COUNTIFS関数』で数えて1を足すことで順位を計算します。
次の表に順位を付けます。
- 下記の表全体を選択して右クリック→『コピー』をクリックします。
グループ ポイント グループ別順位 A 80 A 65 A 90 B 85 B 70 B 75 - ExcelのシートでA1のセルを右クリック→『形式を選択して貼り付け』をクリックします。
- 『貼り付ける形式』で『テキスト』を選択して『OK』をクリックします。
- C2のセルに下記の式を入力して、キーボードの『Enter』を押します。
=COUNTIFS($A$2:$A$7,A2,$B$2:$B$7,">"&B2)+1
- C2のセルの枠の右下をドラッグして、C3~C7のセルにコピーします。
以上で、次のように順位が入力されます。
『20歳未満を対象』という条件を追加する
『グループが自分と同じ人』かつ『年齢が20未満の人』かつ『自分よりポイントが高い人』を『COUNTIFS関数』で数えて>1を足すことで順位を計算します。
次の表に順位を付けます。
- 下記の表全体を選択して右クリック→『コピー』をクリックします。
グループ 年齢 ポイント グループ別順位(20歳未満) A 18 80 A 17 65 A 19 90 B 20 85 B 18 70 B 17 75 - ExcelのシートでA1のセルを右クリック→『形式を選択して貼り付け』をクリックします。
- 『貼り付ける形式』で『テキスト』を選択して『OK』をクリックします。
- C2のセルに下記の式を入力して、キーボードの『Enter』を押します。
=COUNTIFS($A$2:$A$7,A2,$B$2:$B$7,"<20",$C$2:$C$7,">"&C2)+1
- C2のセルの枠の右下をドラッグして、C3~C7のセルにコピーします。
5行目は20歳以上なので対象外です。
6~7行は、5行目を除外した順位が付けられています。
ただ、5行目にも順位が入っていてまぎらわしいので、IF文を使って"対象外"にします。
- C2のセルに下記の式を入力して、キーボードの『Enter』を押します。
=IF(B2<20,COUNTIFS($A$2:$A$7,A2,$B$2:$B$7,"<20",$C$2:$C$7,">"&C2)+1,"対象外")
- C2のセルの枠の右下をドラッグして、C3~C7のセルにコピーします。
以上で、次のように順位が入力されます。
補足:COUNTIFS関数のほうがSUMPRODUCT関数より速い
『COUNTIFS関数』は『Excel2007』で追加されました。それ以前のバージョンでは、『SUMPRODUCT関数』を使う方法がよく紹介されています。
次の2つの式は、どちらも上記で説明したグループ別に20歳未満を対象に順位を付ける式です。
=COUNTIFS($A$2:$A$7,A3,$B$2:$B$7,"<20",$C$2:$C$7,">"&C3)+1 =SUMPRODUCT(($A$2:$A$7=A6)*($B$2:$B$7<20)*($C$2:$C$7>C6))+1 ←上と同等の式
さらに、次の式のように範囲を列全体($A:$Aなど)にした場合、『COUNTIFS関数』は『データが入った最後の行』を検出して無駄な計算を省きますが、『SUMPRODUCT関数』はシートの全行を計算します。
=COUNTIFS($A:$A,A2,$B:$B,"<20",$C:$C,">"&C2)+1 =SUMPRODUCT(($A:$A=A2)*($B:$B<20)*($C:$C>C2))+1 ←上と同等の式
5000行のデータに下記の1~4の式で順位付け。各3回計測。
1:COUNTIFS 行指定 =IF(B2<20,COUNTIFS($A$2:$A$5000,A2,$B$2:$B$5000,"<20",$C$2:$C$5000,">"&C2)+1,"対象外"),"対象外") 2:COUNTIFS 全行 =IF(B2<20,COUNTIFS($A:$A,A2,$B:$B,"<20",$C:$C,">"&C2)+1,"対象外") 3:SUMPRODUCT 行指定 =IF(B2<20,SUMPRODUCT(($A$2:$A$5000=A2)*($B$2:$B$5000<20)*($C$2:$C$5000>C2))+1,"対象外") 4:SUMPRODUCT 全行 =IF(B2<20,SUMPRODUCT(($A:$A=A2)*($B:$B<20)*($C:$C>C2))+1,"対象外")
測定回数 | 1回目 | 2回目 | 3回目 |
---|---|---|---|
1:COUNTIFS 行指定 | 4.46秒 | 4.42秒 | 4.43秒 |
2:COUNTIFS 全行 | 5.45秒 | 5.47秒 | 5.49秒 |
3:SUMPRODUCT 行指定 | 7.53秒 | 7.56秒 | 7.57秒 |
4:SUMPRODUCT 全行 | 44.44秒 | 44.45秒 | 44.47秒 |
参考ページ
あとがき
Excelのシートの最大行数はExcel2003までは6万5536行(256列)で、Excel2007からは104万8576行(1万6384列)あるそうです。
ずっと6万5536行思ってましたが、今はかなり増えてました。
行が増えたこともあって、データの末尾を検出する関数が実装されたんでしょうか。
範囲の指定に列全体(A:A等)を使う場合は、関数によっては処理がめちゃくちゃ重くなるので気をつけた方が良さそうです。