【问题标题】:Compute sample statistics for a data vector with ties which is stored as a frequency table计算数据向量的样本统计数据,该数据向量存储为频率表
【发布时间】:2019-02-13 00:03:27
【问题描述】:

我正在尝试从具有相关值的数据向量中获取一些汇总统计信息(均值、方差和分位数)。特别是,它存储在频率分布表中:唯一数据值var 和关系数frequency

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

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

然后做标准

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

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

【问题讨论】:

    标签: r statistics mean variance quantile


    【解决方案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 是运行的左右百分位数。在图中,“runs”用黑色水平线绘制。

    “跳跃”信息由一行的rx 值和下一行的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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 1970-01-01
      • 2023-01-11
      • 1970-01-01
      相关资源
      最近更新 更多