计算具有关联的数据向量的样本统计信息,该关联存储为频率表

问题描述 投票:1回答:1

我试图从带有绑定值的数据向量中获得一些汇总统计(均值,方差和分位数)。特别是,它存储在频率分布表中:唯一数据值var和数量frequency

我知道我可以使用rep函数首先将矢量扩展为完整格式:

xx <- rep(mydata$var, mydata$frequency)

然后做标准

mean(xx)
var(xx)
quantile(xx)

但频率非常大,我有许多独特的值,这使得程序真的很慢。有没有办法直接从varfrequency计算这些统计数据?

r statistics mean variance quantile
1个回答
1
投票
set.seed(0)
x <- runif(10)                ## unique data values
k <- sample.int(5, 10, TRUE)  ## frequency

n <- sum(k)
xx <- rep.int(x, k)           ## "expanded" data

#################
## sample mean ##
#################

mean(xx)  ## using `xx`
#[1] 0.6339458

mu <- c(crossprod(x, k)) / n  ## using `x` and `k`
#[1] 0.6339458

#####################
## sample variance ##
#####################

var(xx) * (n - 1) / n  ## using `xx`
#[1] 0.06862544

v <- c(crossprod(x ^ 2, k)) / n - mu * mu  ## using `x` and `k`
#[1] 0.06862544

计算分位数涉及更多,但可行。我们首先需要了解分位数是如何以标准方式计算的。

xx <- sort(xx)
pp <- seq(0, 1, length = n)
plot(pp, xx); abline(v = pp, col = 8, lty = 2)

The standard quantile computation is a linear interpolation problem.然而,当数据有关系时,我们可以清楚地看到图中存在“运行”(具有相同值)和“跳跃”(在两个值之间)。仅在“跳跃”时需要线性插值,而在“运行”时,分位数仅为运行值。

以下函数仅使用xk查找分位数。为了演示目的,有一个论点verbose。如果TRUE它将产生一个图表和一个包含“运行”(和“跳跃”)信息的数据框。

find_quantile <- function (x, k, prob = seq(0, 1, length = 5), verbose = FALSE) {

  if (is.unsorted(x)) {
    ind <- order(x); x <- x[ind]; k <- k[ind]
    }

  m <- length(x)     ## number of unique values
  n <- sum(k)        ## number of data
  d <- 1 / (n - 1)   ## break [0, 1] into (n - 1) intervals

  ## the right and left end of each run
  r <- (cumsum(k) - 1) * d
  l <- r - (k - 1) * d

  if (verbose) {

    breaks <- seq(0, 1, d)
    plot(r, x, "n", xlab = "prob (p)", ylab = "quantile (xq)", xlim = c(0, 1))
    abline(v = breaks, col = 8, lty = 2)

    ## sketch each run
    segments(l, x, r, x, lwd = 3)

    ## sketch each jump
    segments(r[-m], x[-m], l[-1], x[-1], lwd = 3, col = 2)

    ## sketch `prob`
    abline(v = prob, col = 3)

    print( data.frame(x, k, l, r) )
    }

  ## initialize the vector of quantiles 
  xq <- numeric(length(prob))

  run <- rbind(l, r)
  i <- findInterval(prob, run, rightmost.closed = TRUE)

  ## odd integers in `i` means that `prob` lies on runs
  ## quantiles on runs are just run values
  on_run <- (i %% 2) != 0
  run_id <- (i[on_run] + 1) / 2
  xq[on_run] <- x[run_id]

  ## even integers in `i` means that `prob` lies on jumps
  ## quantiles on jumps are linear interpolations
  on_jump <- !on_run
  jump_id <- i[on_jump] / 2
  xl <- x[jump_id]      ## x-value to the left of the jump
  xr <- x[jump_id + 1]  ## x-value to the right of the jump
  pl <- r[jump_id]      ## percentile to the left of the jump
  pr <- l[jump_id + 1]  ## percentile to the right of the jump
  p  <- prob[on_jump]   ## probability on the jump
  ## evaluate the line `(pl, xl) -- (pr, xr)` at `p`
  xq[on_jump] <- (xr - xl) / (pr - pl) * (p - pl) + xl

  xq
  }

使用verbose = TRUE将函数应用于上面的示例数据给出:

result <- find_quantile(x, k, prob = seq(0, 1, length = 5), TRUE)

#           x k         l         r
#1  0.2016819 4 0.0000000 0.1111111
#2  0.2655087 2 0.1481481 0.1851852
#3  0.3721239 1 0.2222222 0.2222222
#4  0.5728534 4 0.2592593 0.3703704
#5  0.6291140 2 0.4074074 0.4444444
#6  0.6607978 5 0.4814815 0.6296296
#7  0.8966972 1 0.6666667 0.6666667
#8  0.8983897 3 0.7037037 0.7777778
#9  0.9082078 2 0.8148148 0.8518519
#10 0.9446753 4 0.8888889 1.0000000

数据帧的每一行都是“运行”。 x给出运行值,k是运行长度,lr是运行的左右百分位数。在图中,“运行”以黑色水平线绘制。

r,行的x值和下一行的lx值隐含了“跳跃”的信息。在图中,“跳跃”以红线绘制。

垂直绿线表示我们给出的prob值。

计算的分位数是

result
#[1] 0.2016819 0.5226710 0.6607978 0.8983897 0.9446753

与...相同

quantile(xx, names = FALSE)
#[1] 0.2016819 0.5226710 0.6607978 0.8983897 0.9446753
© www.soinside.com 2019 - 2024. All rights reserved.