Wie berechnet man gewichtete Durchschnittswerte in Google Sheets?


36

Ich besitze ein Google-Blatt, in dem Produkte als Zeilen und Attribute als Spalten aufgeführt sind. Die Attribute jedes Produkts werden auf einer Skala von 1 bis 10 bewertet. Meine letzte Spalte ist ein Durchschnitt dieser Werte (dh =Average(B2:D2)). Dies funktioniert gut, wenn jedes Attribut das gleiche Gewicht hat.

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

Das Problem ist, dass jedes Attribut ein anderes Gewicht haben soll. Beispielsweise ist Attr1 möglicherweise nicht wichtig und sollte nur 50% wert sein, während Attr3 sehr wichtig ist und 300% wert sein sollte.

+--------+-------------+-------+--------------+---------+
|        | 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    |
+--------+-------------+-------+--------------+---------+

Der Wert für die erste Zeile wäre:

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

das könnte berechnet werden mit:

(
  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
)

Wie Sie sehen, kann die Verwaltung sehr schwierig werden, wenn weitere Attribute hinzugefügt werden. Idealerweise suche ich nach einer Lösung, bei der keine temporären Zellen für die Berechnungen erstellt werden müssen.

Gibt es eine eingebaute Funktion oder eine gemeinsame Konvention, mit deren Hilfe ich diese gewichteten Durchschnittswerte berechnen kann?

Antworten:


8

Es gibt keine eingebaute Funktion zur Berechnung des gewichteten Durchschnitts. Sie müssen daher eine benutzerdefinierte Funktion schreiben, um die Verwendung zu vieler temporärer Zellen zu vermeiden. So können Sie Ihr Ziel erreichen.

Gehen Sie zu Extras > Skripte > Skripteditor ... , kopieren Sie den folgenden Code, fügen Sie ihn ein und speichern Sie ihn:

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;
}​

Verwenden Sie es wie folgt:

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

Wo B3:D3sind deine Werte und $B$2:$D$2deine Gewichte? Es ist nicht fehlersicher (die einzige Überprüfung besteht darin, sicherzustellen, dass beide Arrays die gleiche Länge haben), aber es wird den Trick machen.

Im obigen Beispiel versuche ich nicht, die Gewichte aus dem Titel des Attributs zu extrahieren, sondern lese sie aus der zweiten Zeile ( B2:D2), um unser Leben einfacher und klarer zu gestalten. Das $Ergebnis der Formel ändert sich dadurch nicht. Es wirkt sich nur auf das aus, was passiert, wenn Sie die Formel in eine andere Zelle kopieren. Der Teil der Zellreferenz, der auf $ folgt, ändert sich nicht ( Link für weitere Details). Schreiben Sie die Formel einmal in die Zelle E3und kopieren Sie sie in die restlichen Zeilen, um sie in Aktion zu sehen.


Was bedeuten die $Zeichen?
Sinnvolle

@Senseful Ich habe meine Antwort aktualisiert, und Sie können im Allgemeinen Google für dollar sign in exceldas gleiche, da Sie mehr Dokumentation dafür finden.
Lipis

1
Ihre Funktion funktioniert nicht. Aber das funktioniert für mich: gist.github.com/totty90/b58f47dbc430a53d2e5b
Totty.js

1
Es gibt eine andere höher bewertete Antwort auf dieser Seite , die funktioniert und die eingebaute Funktion verwendetsumproduct
Brad Parks

58

Wenn sich Ihre Gewichte in Zeile 2 von B bis L befinden und die Daten, die Sie mitteln möchten, beispielsweise in Zeilen 3 und höher sind, können Sie sumproduct wie folgt verwenden:

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

7
+1 Diese Antwort ist einfach, funktioniert und viel besser als die akzeptierte.
Waqar Lim


2

Der Code von Lipis hat bei mir nicht funktioniert, daher hier ein Update. Dieser Code:

  • Funktioniert mit der aktuellen Version von Google Spreadsheets und adressiert Array-Elemente korrekt

  • prüft, ob die Werte Zahlen sind

  • hat einen Schalter, um Nullwerte zu berücksichtigen oder nicht

Code:

/**
  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

Korrektur des Lipis-Codes für die aktuelle Version von Google Spreadsheets:

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; Ich habe Ihren Code in den neuen Google Sheets getestet und es hat nicht funktioniert, es gab #NUM!als Ergebnis. Der Code, den Lipis gemacht hat, funktioniert immer noch. Sie ignorieren nur das zurückgegebene 2d-Array.
Jacob Jan Tuinstra

0

ARRAYFORMULA () kann einen gewichteten Durchschnitt in Google Spreadsheets (und mehr) berechnen .

Das separate Speichern der Gewichte in B2: D2 vereinfacht das Lesen der Formel. Die Berechnung des gewichteten Durchschnitts für E3 sieht dann ähnlich aus wie oben mit SUMPRODUCT () (Kopieren / Einfügen für 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  |
+--------+-------------+-------+-------------+---------+

Die Verwendung von RegExExtract (), um die Gewichte von $ B $ 1 zu erhalten: $ D $ 1 ist eine einfache Änderung in der ARRAYFORMULA (). Ersetzen Sie den einfachen Bereich durch den komplexeren Ausdruck " iferror(regexextract($B$1:$D$1,"\d+"),100)/100" und die Formel für E3 wird (Kopieren / Einfügen für 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))

Hinweis: Für diesen regulären Ausdruck sind Attributnamen ohne Zahlen erforderlich. Verwenden Sie also AttrA, AttrB und AttrC anstelle von Attr1, Attr2 und Attr3.


0

Nachdem Sie Ihre Frage sorgfältig gelesen haben,

Idealerweise suche ich nach einer Lösung, bei der keine temporären Zellen für die Berechnungen erstellt werden müssen.

Ich habe diese Lösung gefunden, die keine temporären Zellen verwendet.

Formel

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)))

Bildschirmfoto

Bildbeschreibung hier eingeben

Erklärt

Der REGEXEXTRACTextrahiert den Wert in der Kopfzeile nach der ersten geraden Klammer und VALUEwandelt ihn in eine Zahl um. Das IFERRORsetzt den Wert auf, 100wenn nichts gefunden ARRAYFORMULAwird, und ermöglicht die Auswahl eines Bereichs anstelle einzelner Zellen.

Beispiel

Ich habe eine Beispieldatei für Sie erstellt: Wie berechnet man gewichtete Durchschnittswerte in Google Spreadsheets?


0

Da die akzeptierte Antwort Google Apps Script verwendet, habe ich auch ein kleines Snippet erstellt.

Code

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;
}

Bildschirmfoto

Bildbeschreibung hier eingeben

Hinweis

Das Skript folgt der gleichen Logik wie in diesem Beitrag. Der Hauptvorteil ist, dass die Gesamtwerte sofort berechnet werden.

Beispiel

Ich habe eine Beispieldatei für Sie erstellt: Wie berechnet man gewichtete Durchschnittswerte in Google Spreadsheets?


0

Für einfache gewichtete Durchschnitte können Sie den Zellenwert einfach mehrmals addieren. Wenn Sie möchten, dass A1 75% und B1 25% beträgt, können Sie eingeben =AVERAGE (A1,A1,A1,B1). Also speziell für Sie wäre es =AVERAGE (B2,C2,C2,D1,D2,D2,D2,D2,D2,D2), das B2 als die Hälfte von C2 (50%) und D2 als 3x C2 (300%) wiegen würde.

Kompliziertere Sachen liegen über meiner Gehaltsstufe. :)


0

Tatsächlich ergeben beide Versionen Average.weighted und sumproduct das gleiche Ergebnis:

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

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

Ich verwende also lieber die erste, da sie viel einfacher zu handhaben ist, aber ich weiß nicht, wie ich dieser Formel andere Gewichte hinzufügen kann.

Dies ist der Tooltipp, kann aber nicht nur Gewichte und keine zusätzlichen Werte hinzufügen

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

Das ist ein bisschen vage. Versuchen Sie eine neue Frage zu stellen oder ist dies eine Antwort?
jonsca

-2

Es ist ganz einfach, nur gegebene Funktionen zu verwenden.

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

Wobei E-Gehalt die Anzahl der Punkte und G die Wichtigkeit dieser Punkte ist.


2
Diese Antwort wurde bereits gegeben: webapps.stackexchange.com/a/29919/29140
Jacob Jan Tuinstra

@JacobJanTuinstra Warum wird diese Antwort zuerst angezeigt, wenn sie viel niedriger bewertet wird als die, auf die Sie verweisen? webapps stackexchange funktioniert auf mysteriöse Weise ...
e18r
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.