Googleスプレッドシートで加重平均を計算する方法は?


36

製品が行として、属性が列としてリストされているGoogleスプレッドシートがあります。各製品の属性は、1〜10のスケールで評価されます。私の最後の列は、これらの値の平均(つまり=Average(B2:D2))です。各属性の重みが同じ場合、これは正常に機能します。

+--------+-------+-------+-------+---------+
|        | Attr1 | Attr2 | Attr3 | Overall |
+--------+-------+-------+-------+---------+
| Prod 1 | 10    | 8     | 9     | 9       |
| Prod 2 | 2     | 10    | 7     | 6.33    |
| Prod 3 | 4     | 6     | 6     | 5.33    |
+--------+-------+-------+-------+---------+

問題は、各属性に異なる重みを持たせることです。たとえば、Attr1は重要ではなく、50%の価値があるだけですが、Attr3は非常に重要であり、300%の価値があるはずです。

+--------+-------------+-------+--------------+---------+
|        | Attr1 (50%) | Attr2 | Attr3 (300%) | Overall |
+--------+-------------+-------+--------------+---------+
| Prod 1 | 10          | 8     | 9            | 8.89    |
| Prod 2 | 2           | 10    | 7            | 7.11    |
| Prod 3 | 4           | 6     | 6            | 5.78    |
+--------+-------------+-------+--------------+---------+

最初の行の値は次のとおりです。

(10*0.5 + 8*1 + 9*3) / (0.5+1+3) = 8.89

以下を使用して計算できます:

(
  B2*(IFERROR(REGEXEXTRACT(B1, "\d+"), 100)/100) 
  + C2*(IFERROR(REGEXEXTRACT(C1, "\d+"), 100)/100)
  + D2*(IFERROR(REGEXEXTRACT(D1, "\d+"), 100)/100) 
) / (
  IFERROR(REGEXEXTRACT(B1, "\d+"), 100)/100
  + IFERROR(REGEXEXTRACT(C1, "\d+"), 100)/100
  + IFERROR(REGEXEXTRACT(D1, "\d+"), 100)/100
)

ご覧のとおり、属性が追加されると管理が非常に難しくなる可能性があります。理想的には、計算を支援するために一時的なセルを作成する必要のないソリューションを探しています。

これらの加重平均の計算に役立つ組み込み関数または一般的な規則はありますか?

回答:


8

加重平均を計算するための組み込み関数はないため、一時的なセルを使いすぎないようにするには、カスタム関数を作成する必要があります。目標を達成する方法は次のとおりです。

移動ツール > スクリプト > スクリプトエディタ...、コピー/怒鳴るコードを貼り付けて、それを保存します。

function weightedAverage(v, w) {
  var sum_v = 0;
  var sum_w = 0;

  if (v[0].length != w[0].length) {
    return "#ERROR: Incorrect number of values and weights";  
  }

  for (var c = 0; c < v[0].length; ++c) {
    sum_v += v[0][c] * w[0][c]; 
    sum_w += w[0][c]; 
  }

  return sum_v/sum_w;
}​

次のように使用します。

=weightedAverage(B3:D3,$B$2:$D$2) 

B3:D3あなたの価値と$B$2:$D$2重みはどこにありますか。エラー防止ではありません(唯一のチェックは、両方の配列の長さが同じであることを確認することです)が、うまくいきます。

上記の例では、属性のタイトルから重みを抽出しようとはしていませんが、2行目(B2:D2)からそれらを読み取って、より簡単でわかりやすいものにします。$式の結果が変化していません。別のセルに数式をコピーしているときに何が起こっているかにのみ影響します。$に続くセル参照の部分は変更されません(詳細についてはリンク)。セルに式を1回書き込み、E3それを残りの行にコピーして、実際の動作を確認します。


何をする$兆候はどういう意味ですか?
意味のある

@Senseful私は私の答えを更新しましたが、dollar sign in excelそれについてのドキュメントを見つけることができるので、一般的にGoogleはそれが同じことであることができます。
リピス

1
関数が機能しません。しかし、これは私のために働く:gist.github.com/totty90/b58f47dbc430a53d2e5b
Totty.js

1
このページには、機能が組み込まれており、組み込み機能を使用する別の高い評価の回答がありますsumproduct
ブラッドパークス

58

重みがBからLまでの行2にあり、平均するデータが行3以上にある場合、次のようにsumproductを使用できます。

=sumproduct(B$2:L$2, C3:L3)/sum(B$2:L$2)

7
+1この答えはシンプルで、機能し、受け入れられているものよりもはるかに優れています。
2013


2

リピスのコードは私には機能していなかったので、ここにアップデートがあります。このコード:

  • 配列要素を正しくアドレス指定する現在のバージョンのGoogleスプレッドシートで動作します

  • 値が数値かどうかを確認します

  • ゼロ値を考慮するかどうかを切り替えるスイッチがあります

コード:

/**
  v - Values range
  w - Weights range
  z - count zero values?
*/

function weightedAverage(v, w, z) {
  var sum_v = 0;
  var sum_w = 0;

  if (v.length != w.length) {
    return "#ERROR: Incorrect number of values and weights";  
  }

  for (var c = 0; c < v.length; ++c) {
    if (!z && Number(v[c][0])!=0) {
      sum_v += Number(v[c][0]) * Number(w[c][0]); 
      sum_w += Number(w[c][0]); 
    }
  }

  return sum_v/sum_w;
}

0

Googleスプレッドシートの現在のバージョンで動作するようにLipisのコードを修正する:

function weightedAverage(v, w) {
  var sum_v = 0;
  var sum_w = 0;

  if (v.length != w.length) {
    return "#ERROR: Incorrect number of values and weights";  
  }

  for (var c = 0; c < v.length; ++c) {
    sum_v += v[c] * w[c]; 
    sum_w += w[c] * 1; 
  }

  return sum_v/sum_w;
}​

-1; 新しいGoogleスプレッドシートでコードをテストしましたが、機能しませんでした#NUM!。Lipisが作成したコードはまだ動作します。返される2d-arrayのみを無視しています。
ジェイコブヤントゥインストラ14

0

ARRAYFORMULA()は、Googleスプレッドシート(およびその他)で加重平均を計算できます。

重みをB2:D2に個別に保存すると、式の読み取りが簡単になります。E3の加重平均の計算は、上記のSUMPRODUCT()に似ています(E4およびE5のコピー/貼り付け):

=ARRAYFORMULA(sum(B3:D3 * $B$2:$D$2)/sum($B$2:$D$2))

+--------+-------------+-------+-------------+---------+
|        | AttrA (50%) | AttrB | AttrC (300%)| Overall |
| Weight:|        50%  |  100% |        300% |         |
+--------+-------------+-------+-------------+---------+
| Prod 1 |       10    |  8    |       9     | 8.8889  |
| Prod 2 |        2    | 10    |       7     | 7.1111  |
| Prod 3 |        4    |  6    |       6     | 5.7778  |
+--------+-------------+-------+-------------+---------+

RegExExtract()を使用して$ B $ 1:$ D $ 1から重みを取得することは、ARRAYFORMULA()の簡単な変更です。単純な範囲をより複雑な式 " iferror(regexextract($B$1:$D$1,"\d+"),100)/100"に置き換えると、E3の式は次のようになります(E4およびE5のコピー/貼り付け)。

=ARRAYFORMULA(sum(B3:D3 * iferror(regexextract($B$1:$D$1,"\d+"),100)/100)/sum(iferror(regexextract($B$1:$D$1,"\d+"),100)/100))

NBその正規表現には、番号のない属性名が必要です。そのため、Attr1、Attr2およびAttr3の代わりにAttrA、AttrBおよびAttrCを使用します。


0

質問を注意深く読んで、

理想的には、計算を支援するために一時的なセルを作成する必要のないソリューションを探しています。

一時的なセルを使用しないこのソリューションを思いつきました。

weights = ARRAYFORMULA(IFERROR(VALUE(REGEXEXTRACT($B$1:$D$1,"\((\d+)")),100))

=SUMPRODUCT(B3:D3, weights) / SUM(weights)

copy / paste
=SUMPRODUCT(B2:D2, ARRAYFORMULA(IFERROR(VALUE(REGEXEXTRACT($B$1:$D$1,"\((\d+)")),100)))/SUM(ARRAYFORMULA(IFERROR(VALUE(REGEXEXTRACT($B$1:$D$1,"\((\d+)")),100)))

スクリーンショット

ここに画像の説明を入力してください

説明した

REGEXEXTRACT最初の直線ブラケット後ヘッダの値を抽出し、VALUE数値に変換します。IFERRORで値を設定します100何も見つからなかった場合ARRAYFORMULA、それは可能ではなく、個々の細胞よりも、範囲を選択するようになります。

サンプルファイルを作成しました:Googleスプレッドシートで加重平均を計算する方法は?


0

受け入れられた答えはGoogle Apps Scriptを使用しているため、小さなスニペットも作成しました。

コード

function weightedAverage(v, w) {
  var weights = [], sumWeights = 0;
  for(var k = 0, kLen = w[0].length; k < kLen; k++) {
    var m = w[0][k].match(/\((\d+)/), value;
    if(!m) {
      value = 100;
    } else {
      value = Number(m[1]);
    }
    weights.push(value);
    sumWeights += value;
  }

  var output = [];
  for(var i = 0, iLen = v.length; i < iLen; i++) {
    var sumProduct = 0;
    for(var j = 0, jLen = v[0].length; j < jLen; j++) {
      sumProduct += v[i][j] * weights[j]; 
    }
    output.push(sumProduct / sumWeights);
  } 
  return output;
}

スクリーンショット

ここに画像の説明を入力してください

注意

スクリプトは、この投稿で示したのと同じロジックに従います。主な利点は、全体の値を一度に計算できることです。

サンプルファイルを作成しました:Googleスプレッドシートで加重平均を計算する方法は?


0

以下のための単純な加重平均、あなただけのセルの値を複数回追加することができます。A1を75%に、B1を25%にしたい場合、を入力できます=AVERAGE (A1,A1,A1,B1)。したがって、=AVERAGE (B2,C2,C2,D1,D2,D2,D2,D2,D2,D2)B2はC2の半分(50%)で、D2は3x C2(300%)の重さである、ということになります。

もっと複雑なものは、私の給与等級を上回っています。:)


0

実際には、Average.weightedとsumproductの両方のバージョンで同じ結果が得られます。

AVERAGE.WEIGHTED("Values","Weight")

SUMPRODUCT("Numbers","Weight")/sum("Weight")

だから、私はむしろそれを扱うのがより簡単なので、最初のものを使用しますが、この式に他の重みを追加する方法がわかりません。

これはツールチップですが、追加の値ではなく、重みのみを追加する方法がわかりません

AVERAGE.WEIGHTED(values, weights, [additional_values, ...], [additional_weights, ...])

これは少しあいまいです。新しい質問をしようとしていますか、これは答えですか?
jonsca

-2

指定された関数のみを使用する非常に簡単な方法があります。

=(sumproduct(E5:E9;G5:G9)/sum(E5:E9))   

ここで、Eの内容はポイント数、Gはそれらのポイントの重要度です。


2
その答えはすでに与えられています:webapps.stackexchange.com/a/29919/29140
ジェイコブJan Tuinstra 14

@JacobJanTuinstra参照しているものよりも格付けが低い場合、この回答が最初に表示されるのはなぜですか?webapps stackexchangeは謎めいた方法で動作します...
e18r
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.