いきなり答える備忘録

Google Workspace・Microsoft 365・LibreOfficeなどに関するメモ

(Excel)データの重複を除いてカウントする方法

 Excelでデータの重複を除外してカウントする、言い換えれば値が何種類あるかカウントする方法についてです。
 メニュー操作で重複を除く方法も考えられますがここでは関数を使う例を紹介します。式はそれほど難しくないものの空白セルの扱いなどで注意が必要です。


値の重複を除いたセル数をカウントする方法

COUNTIF関数を使う方法

 次の画像ではD3セルに式を入力して、B3:B10セルのデータの重複を除外してカウントしています。結果は4であり、つまり4種類の値(みかん、メロン、りんご、かき)があることを示しています。

 D3セル

=SUM(1/COUNTIF(B3:B10,B3:B10))

 まずCOUNTIF関数を使い、それぞれのセルの値がいくつあるかカウントしてその逆数を求めています。そのセルの値が3つあればそのセルは1/3という数値に変換されるというわけです。最終的に各セルが変換された数値をSUM関数で合計すれば、重複を除いたカウント(値の種類の数)になります。
 なおSUM関数でなくSUMPRODUCT関数が用いられることもあります。特に旧バージョンではSUMPRODUCTが選択されますが、少なくともMicrosoft365では積極的にSUMPRODUCTを使う理由はなさそうです。



 次の画像は、わかりやすいように「1/COUNTIF(B3:B10,B3:B10)」の部分だけを実行した結果です。2つある値(メロン、リンゴ)はそれぞれ1/2=0.5に、3つある値(みかん)は1/3=0.333…に変換されているのがわかります。これらを足すと「4」というカウント結果になります。

 


 ここで注意点です。
 上記の画像を見てイヤな予感がした方もいると思いますが、この数式では誤差が発生する恐れがあります。
 次の画像では27個ある1種類の値について上記と同じカウントの仕方をしています(このように縦横に並ぶ値もカウント可能です)。結果は「1」となっているもののH3セルに「=F3=1」という判定式を入力すると結果はFALSEになります。つまりこの数値はセル上の見た目こそ「1」ですが正確には1ではありません(1/27を27個足しても1にならない)。

 


 視覚的に結果を確認するためだけの用途であれば気にする必要はありませんが、さらに比較や計算に用いる場合はROUND関数などで丸めておくのが無難です(以下ではこの対応は省略します。また、UNIQUE関数を用いる例では不要)。

 


 繰り返しになりますが、縦横に並んだセルも引数の範囲を変えるだけで全く同様にカウントできるのが便利な点です。

UNIQUE関数を使う方法

 データの重複を除いた結果を返す、UNIQUE関数を使う方法です。
 次の画像は上記の例と同様に、B3:B10の範囲のデータについて重複を除いてカウントしています。

 D3セル

=ROWS(UNIQUE(B3:B10))

 UNIQUE関数で重複を除き、ROWS関数でその行数をカウントしています。
 ROWS関数ではなくCOUNTA関数を使う方法も考えられますが、複数列が重複する行を除いてカウントする例(下記参照)でも全く同じように使えるのでROWS関数で統一しています。
 


 さらに補足ですが、ROWS関数ではなくCOUNTA関数を使えば空白セルがあってもカウントせずに済むのではないか、と思われるかもしれません。
 しかしUNIQUE関数により空白セルが0に変換されてしまうため1種類とカウントされてしまい、これはROWS関数を使ったのと同じ結果になります。ちなみにデータに空白セルと数値の0が含まれる場合はそれぞれ別にカウント(2種類)されます。

 


 データが縦横のセルに並ぶ例です。UNIQUE関数に複数列を指定すると行単位で重複を除いた結果となるので、セル単位で重複を除いてカウントしたい場合はいったんTOCOL関数で縦1列に並べ直したうえでUNIQUE関数を適用する必要があります。

 F3セル

=ROWS(UNIQUE(TOCOL(B3:D9)))

重複行の重複を除いた行数をカウントする方法

COUNTIFS関数を使う方法

 複数の列の値がいずれも一致する場合は重複するデータ(行)とみなし、重複を除いた行数をカウントする例です。
 次の画像では、重複する行(B列の値とC列の値が共に重複する行)の重複を除いた行数「7」を得ています。
 なお10行あるデータのうち「岡山県、もも」「大分県、みかん」「熊本県、もも」が2行ずつあるので重複を除いた行数は7となります。

 E3セル

=SUM(1/COUNTIFS(B3:B12,B3:B12,C3:C12,C3:C12))

 基本的には最初の例(セルの重複を除いてカウントする)と同じ式ですが、こちらではCOUNTIFS関数を使って「B列とC列がいずれも他の行と重複する行」を1/2とか1/3といった数値に変換しています。最後にSUM関数で合計すれば求める値となります。

UNIQUE関数を使う方法

 こちらはUNIQUE関数を使う例です。

 F3セル

=ROWS(UNIQUE(B3:C12))

 UNIQUE関数で複数列の重複を除き、ROWS関数で行数をカウントしています。複数列の重複を除く場合はこちらの方が簡単です。
 ROWSをCOUNTAに代えるとセル単位で数えてしまい「14」になるため注意が必要です。

備考:空白セルがある場合

 上記の例ではすべてのセルに値があるデータのみ扱いましたが、空白セル(未入力セル)がある場合には注意が必要です。
 ただ、あらゆるケースを網羅するのは大変なので限られたケースについて補足しておきます。
 まず最初に紹介したCOUNTIF関数の例ですが、データに空白セルが含まれるとエラーになります。

 


 そこで次の画像では空白セルを0に変換しておき合計するようにしています。

 D3セル

=SUM(IF(B3:B10="",0,1/COUNTIF(B3:B10,B3:B10)))

 正確には空文字列(="")であるデータもカウントされなくなるものの、実用的にはほぼこれで足りるかと思います。「B3:B10=""」を「ISBLANK(B3:B10)」に代えればよさそうですが空白セルと空文字列が混在する場合など一層カオスな結果になりますのでご注意ください。
 


 次はUNIQUE関数の例です。上記例でも触れましたが、こちらは空白セルを1種類の値としてカウントしてしまいます。
 UNIQUE関数が空白セルを0に変換するので、ROWS関数をCOUNTA関数に代えても結果は同じです。



 そこで次の画像ではFILTER関数を併用し、空白セルを除外しておいてUNIQUE関数及びROWS関数を適用しています。

 D3セル

=ROWS(UNIQUE(FILTER(B3:B10,B3:B10<>"")))

 ただしこれも空白セルのほか空文字列(="")がカウントされなくなります。