Como calcular médias ponderadas no Planilhas Google?

36

Eu tenho um Planilhas Google onde os produtos são listados como linhas e atributos como colunas. O atributo de cada produto é classificado em uma escala de 1 a 10. Minha última coluna é uma média desses valores (ie =Average(B2:D2)). Isso funciona bem se cada atributo tiver o mesmo peso.

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

O problema é que eu quero que cada atributo tenha um peso diferente. Por exemplo, Attr1 pode não ser importante e deve valer apenas 50%, enquanto Attr3 é muito importante e deve valer 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    |
+--------+-------------+-------+--------------+---------+

O valor para a primeira linha seria:

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

que pode ser calculado usando:

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

que, como você pode ver, pode se tornar muito difícil de gerenciar à medida que mais atributos são adicionados. Idealmente, estou procurando uma solução que não exija a criação de células temporárias para ajudar nos cálculos.

Existe alguma função interna ou uma convenção comum que possa me ajudar a calcular essas médias ponderadas?

Sensível
fonte

Respostas:

8

Não há nenhuma função integrada para calcular a média ponderada, portanto, você deve escrever uma função personalizada para evitar o uso de muitas células temporárias. Então, aqui está como você pode alcançar seu objetivo.

Vá para Ferramentas > Scripts > Editor de scripts ... , Copie / cole o código abaixo e salve-o:

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

Use-o como:

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

Onde B3:D3 estão seus valores e $B$2:$D$2pesos. Não é à prova de erro (a única verificação é garantir que ambas as matrizes tenham o mesmo comprimento), mas isso funcionará.

No exemplo acima, não estou tentando extrair os pesos do título do atributo, mas estou lendo-os da segunda linha ( B2:D2) para tornar nossa vida mais fácil e clara. O $não está alterando o resultado da fórmula. Isso afeta apenas o que está acontecendo quando você está copiando a fórmula em outra célula. A parte da referência da célula após o $ não será alterada ( link para mais detalhes). Escreva a fórmula uma vez na célula E3e copie-a para o restante das linhas para vê-la em ação.

Lipis
fonte
O que $significam os sinais?
Sensuous
@Senseful Atualizei minha resposta, e você pode dollar sign in excelprocurar no Google em geral pela mesma coisa, já que encontrará mais documentação para isso.
Lipis
1
Sua função não funciona. Mas isso funciona para mim: gist.github.com/totty90/b58f47dbc430a53d2e5b
Totty.js
1
Há outra resposta mais elevado avaliado desta página que as obras e usa o construído em funçãosumproduct
Brad Parks
58

Se seus pesos estão na linha 2 de B a L e os dados que você deseja calcular em média estão nas linhas 3 e superiores, digamos, você pode usar sumproduct da seguinte maneira:

=sumproduct(B$2:L$2, C3:L3)/sum(B$2:L$2)
Brendan Murphy
fonte
7
+1 esta resposta é simples, funcionando e muito melhor que a aceita.
Afr
7

O Google parecia ter escutado. Pelo menos na minha instância do Planilhas Google, a função AVERAGE.WEIGHTEDexiste. Pela ajuda:

=AVERAGE.WEIGHTED(values,
                  weights,
                  [additional_values, ...],
                  [additional_weights, ...])
Tony Shouse
fonte
Link para ajudar, por favor. Não consegui encontrar.
paragbaxi
2

O código de Lipis não estava funcionando para mim, então aqui está uma atualização. Este código:

  • funciona com a versão atual das planilhas do Google, abordando corretamente os elementos da matriz

  • verifica se os valores são números

  • tem uma opção para considerar valores zero ou não

Código:

/**
  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;
}
Zhenya Morozov
fonte
0

Corrigindo o código da Lipis para funcionar na versão atual das planilhas do Google:

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;
}​
Sai
fonte
-1; Testei seu código no novo Planilhas Google e não funcionou, deu #NUM!como resultado. O código que Lipis criou ainda funciona. Você está ignorando apenas o 2d-array que está sendo retornado.
Jacob Jan Tuinstra
0

ARRAYFORMULA () pode calcular uma média ponderada nas planilhas do Google (e mais).

Armazenar os pesos separadamente em B2: D2 simplifica a leitura da fórmula. O cálculo da média ponderada do E3 é semelhante ao SUMPRODUCT () acima (copiar / colar para o E4 e 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  |
+--------+-------------+-------+-------------+---------+

Usar RegExExtract () para obter pesos de $ B $ 1: $ D $ 1 é uma alteração simples na ARRAYFORMULA (). Substitua o intervalo simples pela expressão mais complexa " iferror(regexextract($B$1:$D$1,"\d+"),100)/100" e a fórmula para E3 se torna (copiar / colar para E4 e 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 Esse regexp requer nomes de atributos sem números; então, use AttrA, AttrB e AttrC em vez de Attr1, Attr2 e Attr3.

MW
fonte
0

Depois de ler sua pergunta com cuidado,

Idealmente, estou procurando uma solução que não exija a criação de células temporárias para ajudar nos cálculos.

Eu vim com esta solução, que não usa células temporárias.

Fórmula

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

Captura de tela

insira a descrição da imagem aqui

Explicado

Ele REGEXEXTRACTextrairá o valor no cabeçalho após o primeiro colchete e VALUEo converterá em um número. Ele IFERRORdefinirá o valor como 100se nada for encontrado e ARRAYFORMULApermitirá selecionar um intervalo, em vez de células individuais.

Exemplo

Criei um arquivo de exemplo para você: como calcular médias ponderadas nas planilhas do Google?

Jacob Jan Tuinstra
fonte
0

Como a resposta aceita está usando o Script do Google Apps, também criei um pequeno trecho.

Código

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

Captura de tela

insira a descrição da imagem aqui

Nota

O script seguirá a mesma lógica apresentada nesta postagem. A principal vantagem é que ele calculará os valores gerais de uma só vez.

Exemplo

Criei um arquivo de exemplo para você: como calcular médias ponderadas nas planilhas do Google?

Jacob Jan Tuinstra
fonte
0

Para médias ponderadas simples , você pode adicionar o valor da célula várias vezes. Como se você deseja que A1 seja 75% e B1 seja 25%, você pode inserir =AVERAGE (A1,A1,A1,B1). Tão especificamente para o seu, seria =AVERAGE (B2,C2,C2,D1,D2,D2,D2,D2,D2,D2), o que pesaria B2 como metade de C2 (50%) e D2 como 3x C2 (300%).

Coisas mais complicadas estão acima da minha nota de pagamento. :)

Jason
fonte
0

Na verdade, ambas as versões Average.weighted e sumproduct oferecem o mesmo resultado:

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

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

Por isso, prefiro usar o primeiro, já que é muito mais simples de lidar, mas não sei como adicionar outros pesos a essa fórmula.

Esta é a dica de ferramenta, mas não sabe como adicionar apenas pesos e não valores adicionais

AVERAGE.WEIGHTED(values, weights, [additional_values, ...], [additional_weights, ...])
João Carpio
fonte
Isso é um pouco vago. Você está tentando fazer uma nova pergunta ou isso é uma resposta?
jonsca
-2

Existe uma maneira bastante simples de usar apenas determinadas funções.

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

onde E conteúdo é o número de pontos e G a importância desses pontos.

Adão
fonte
2
Essa resposta já foi dada: webapps.stackexchange.com/a/29919/29140
Jacob Jan Tuinstra
@JacobJanTuinstra Por que essa resposta aparece primeiro se ela é classificada muito abaixo da resposta que você está consultando? O
stackexchange da