6

I wanted to use a function that would quickly give me a standard deviation of a vector ad allow me to include weights for elements in the vector. i.e.

sd(c(1,2,3))     #weights all equal 1
#[1] 1
sd(c(1,2,3,3,3))  #weights equal 1,1,3 respectively
#[1] 0.8944272

For weighted means I can use wt.mean() from library(SDMTools) e.g.

>  mean(c(1,2,3))
[1] 2
>     wt.mean(c(1,2,3),c(1,1,1))
[1] 2
> 
>     mean(c(1,2,3,3,3))
[1] 2.4
>     wt.mean(c(1,2,3),c(1,1,3))
[1] 2.4

but the wt.sd function does not seem to provide what I thought I wanted:

>   sd(c(1,2,3))
[1] 1
>     wt.sd(c(1,2,3),c(1,1,1))
[1] 1
>     sd(c(1,2,3,3,3))
[1] 0.8944272
>     wt.sd(c(1,2,3),c(1,1,3))
[1] 1.069045

I am expecting a function that returns 0.8944272 from me weighted sd. Preferably I would be using this on a data.frame like:

data.frame(x=c(1,2,3),w=c(1,1,3))
BenMorel
  • 34,448
  • 50
  • 182
  • 322
user1320502
  • 2,510
  • 5
  • 28
  • 46
  • Note the docs from `SDMTools::wt.var`: "wt.var is the unbiased variance of the weighted mean calculation using equations of GNU Scentific Library". – Roland Aug 09 '13 at 11:41

2 Answers2

9
library(Hmisc)
sqrt(wtd.var(1:3,c(1,1,3)))
#[1] 0.8944272
Roland
  • 127,288
  • 10
  • 191
  • 288
4

You can use rep to replicate the values according to their weights. Then, sd can be computed for the resulting vector.

x <- c(1, 2, 3) # values
w <- c(1, 1, 3) # weights

sd(rep(x, w))
[1] 0.8944272
Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168