
A B C D E
1 0 2 1 3
まず、上記の表で、D1はA1からC1までの合計です。
ここでE1で
= -A1/F1*LN(A1/F1)-B1/F1*LN(B1/F1)-C1/F1*LN(C1/F1)
という特殊な演算(詳しくはエントロピーの計算です)をしたいと思います。
以下詳細な説明です。
A1/F1 → 分子が各セル、分母が合計
LN(A1/F1) → 上記の自然対数を求めます
-A1/F1*LN(A1/F1) → 上の二つを掛けて、負にします
-A1/F1*LN(A1/F1)-B1/F1*LN(B1/F1)-C1/F1*LN(C1/F1) → 行全ての合計
計算式は上記であっているのですが、2つ問題があります。
・実際は列が多く、各セルの計算式を上記のように書くことはできません。まとめて関数を記述することはできないでしょうか?
・自然対数の計算(=LN(値))は、値に0が入ると、エラー(#NUM!)
が出てしまいます。上記の計算式では、#NUM!が起こります。上手く値の0は飛ばして行全体の合計を出すことはできないでしょうか?
以上、ご教授の方、よろしくお願い致します。
A 回答 (4件)
- 最新から表示
- 回答順に表示

No.4
- 回答日時:
ご質問の趣旨を取り違えていましたらすみません。
素朴に配列数式でもいけるように思います。
E1: =SUM(IF(A1:C1=0,0,-(A1:C1/F1)*LN(A1:C1/F1)))
を配列数式として入力。
※通常の数式は、数式を入力した後Enterキーで確定しますが、
これは配列数式なので、CtrlとShiftを押しながらEnterで確定してください。
略解
A1からC1の各セルの値Xについて、
X=0ならば0を、でなければ-(X/F1)*LN(X/F1) を返した配列の和を返す。
或いは、LN(1)=0であることを利用して、
E1: =SUMPRODUCT(-(A1:C1/F1)*LN((A1:C1=0)+(A1:C1<>0)*A1:C1/F1))
とする方法もあります。こちらはEnterキーのみで確定してOKです。
略解
A1からC1の各セルの値Xについて、
-(X/F1)*LN(【Xが0ならば1,Xが0でなければX/F1】)) を返した値の和を返す。
A1~C1の値が0でない場合に質問文の数式を同じ値が返ることは確認しました。
0を含む場合の解釈があっているかどうか…。
No.3
- 回答日時:
ka_na_deです。
2番目の回答では、
データが複数行あると仮定して説明しました。
もし、1行だけでよいのなら、
1枚のシートで簡単にできます。
その場合は補足してください。
また、説明します。
No.2
- 回答日時:
関数の方法を紹介します。
1)ファイルを新規作成して、シートを6枚用意してください。
Sheet1~Sheet6として説明します。
2)Sheet1に元のデータを貼り付けてください。
(見出し行なしで説明します。)
(合計の列は不要です。)
3)Sheet2に合計を計算します。
Sheet2のA1セルに
=SUM(Sheet1!1:1)
と入力し、以下コピー&ペースト
4)Sheet3に割合?を計算します。(各値/合計)
Sheet3のA1セルに
=Sheet1!A1/Sheet2!$A1
と入力し、以下コピー&ペースト
その後、列方向にもコピー&ペースト
5)Sheet4に対数を計算します。
Sheet4のA1セルに
=IF(Sheet3!A1=0,0,LN(Sheet3!A1))
と入力し、以下コピー&ペースト
その後、列方向にもコピー&ペースト
6)Sheet5に(各値/合計)*対数(各値/合計)*(-1)を計算
Sheet5のA1セルに
=Sheet3!A1*Sheet4!A1*(-1)
と入力し、以下コピー&ペースト
その後、列方向にもコピー&ペースト
6)Sheet6に 行すべての合計を計算します。
Sheet6のA1セルに
=SUM(Sheet5!1:1)
と入力し、以下コピー&ペースト
以上です。
Sheet1の元データは、
EXCEL2003では、65536行、256列まで可能です。
EXCEL2007では、もっといけるようです。
尚、シート名は、式をすべて入力後に、
シートタブ上で右クリックして変更すれば、
式のシート名も自動で変更できます。
必要であれば、適当に分かりやすい名前にしてください。
また、途中の計算シートが邪魔であれば、
シートを選択し、
「書式」→「シート」→「表示しない」
とすることもできます。
Sheet別に計算する、というのは思いつきませんでした。
ありがとうございます!!
試してみます!
補足など細かい配慮までありがとうございました。
No.1
- 回答日時:
F1セルの内容が不明ですが、
「D1はA1からC1までの合計」を「F1はA1からC1までの合計」
と読み替えて回答いたします。
まず #NUM! への対処法ですが、一般的にはiserr関数とif関数の組合せで対処する
のが常套かと思います。
例)
=IF(ISERR(LN(A1)),0,LN(A1))
LN(A1)がエラー値のときには0を返します。
それと長い式への対応ですが、これは隠しセルをたくさん使うか、ユーザー定義関数を
用いるしかないと思います。
隠しセルを使用する場合は、実際の事例により対処が異なりますが、基本的にはたとえ
ば、GA、GB、GCセル(それぞれ183、184、185列目)を使って
GA=-A1/F1*LN(A1/F1)
GB=-B1/F1*LN(B1/F1)
GC=-C1/F1*LN(C1/F1)
などとし、GA、GB、GCを使って値を求める、といったやりかたです。
最後、ユーザー定義関数を用いる方法ですが、ご質問の事例をコード化しました。
Function fENT(rIdx As Long, cIdx As Integer) As Double
Application.Volatile
Dim AX, BX, CX, FX As Double
If cIdx < 5 Then
fENT = 0
Exit Function
End If
AX = Val(Cells(rIdx, cIdx - 4).Value)
BX = Val(Cells(rIdx, cIdx - 3).Value)
CX = Val(Cells(rIdx, cIdx - 2).Value)
FX = AX + BX + CX
fENT = 0
If AX <> 0 Then fENT = fENT - AX / FX * Log(AX / FX)
If BX <> 0 Then fENT = fENT - BX / FX * Log(BX / FX)
If CX <> 0 Then fENT = fENT - CX / FX * Log(CX / FX)
End Function
1)[Alt]+[F11]を押す。
2)左側のプロジェクトエクスプローラーのVBAProjectを右クリックし
[挿入]→[標準モジュール]
3)右側のエディタエリアに上のコードを貼り付け
以上でシート上からfENT関数を使えるようになります。
使い方はE1セルに=fent(ROW(),COLUMN())と入れて下さい。
あとは上記コードを書き換えることで対応することになるのですが、その方法については
別途ご質問頂いた方がよろしいかと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
首吊りどこ締めるの
-
血液検査の結果が悪くefgrの値...
-
腕を見たら黄色くなってる部分...
-
excel関数で TRUEやFALSEについて
-
検便についてです。 便は取れた...
-
風俗店へ行く前のご飯
-
彼女のことが好きすぎて彼女の...
-
値が入っているときだけ計算結...
-
2つの数値のうち、数値が小さい...
-
小数点以下を繰り上げたものを...
-
精液の落とし方を教えてください
-
ワードのページ番号をもっと下...
-
筋トレするとチンコが縮んじゃ...
-
病院側から早く来てくださいと...
-
FFPやMAPとは?
-
「内数」という言葉の意味がよ...
-
リンク先のファイルを開かなく...
-
Excel 数値の前の「 ' 」を一括...
-
Excelグラフのラベルオプション...
-
Excel条件付書式(残業45時間以...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
首吊りどこ締めるの
-
検便についてです。 便は取れた...
-
血小板増加について
-
彼女のことが好きすぎて彼女の...
-
Excel 数値の前の「 ' 」を一括...
-
病院側から早く来てくださいと...
-
VLOOKUP関数を使用時、検索する...
-
腕を見たら黄色くなってる部分...
-
値が入っているときだけ計算結...
-
リンク先のファイルを開かなく...
-
2つの数値のうち、数値が小さい...
-
風俗店へ行く前のご飯
-
小数点以下を繰り上げたものを...
-
一番多く表示のある値(文字列...
-
MIN関数で空白セルを無視したい...
-
勃起する時って痛いんですか? ...
-
エクセルで空白セルを含む列の...
-
増減表のプラスマイナスの符号...
-
【Excelで「正弦波」のグラフを...
-
エクセルで数式の答えを数値と...
おすすめ情報