【问题标题】:Creating percentiles of data set创建数据集的百分位数
【发布时间】:2020-06-01 16:01:56
【问题描述】:

我尝试过使用 quantile 函数,但没有达到预期效果。

我也使用了新功能

 percentile <- function(Df, percentile = 50)
   {
   Df_Names <- names(Df)
  percentile <- percentile/100
  f <- function(x, p) c(NA, x[-length(x)]) + p * c(NA, diff(x))
  while(length(which(!is.na(Df[[length(Df)]]))) > 1)          
  {
Df <- cbind(Df, f(Df[[length(Df)]], percentile))
}
setNames(Df, c(Df_Names, paste0("v", 1:(length(df) - length(df_Names)))))
}

Output=data.frame(pecentile(df, percentile = 50))

假设我们找到了我提到百分位数的 P50。注意:我使用 excel 计算百分位数函数,但使用 R 的结果应该相同。在大多数情况下,每列有数千个数据点,R 计算它们的时间效率更高。

一个示例数据集是

  Date           data
  2020-01-01      49.5
  2020-02-01      49.7
  2020-03-14      48.5
  2020-05-02      50.2

我正在尝试使用脚本之前的列作为起点,使脚本产生百分位输出。但是,V1 之后的列的百分位数计算方式与 V1 不同。如图所示

V1 计算

其中 49.35 是在 Excel 中使用红色框中的 48.5 和 50.2 计算的百分位数,而 49.1 是在与红色框重叠的蓝色框中使用 49.7 和 48.5 的结果。

和V2计算

其中 49.225 是在红色框中使用 49.1 和 49.35 的结果,而 49.35 是在与红色框重叠的蓝色框中使用 49.6、49.1 和 49.35 的结果。

V2 计算开始时相同,但它上面的计算包括相邻单元格加上相邻单元格下面的单元格,脚本不这样做。

这个脚本的结果应该是:

  Date           data    V1     V2      V3
  2020-01-01      49.5   49.6   49.35    49.2875
  2020-02-01      49.7   49.1   49.225
  2020-03-14      48.5   49.35
  2020-05-02      50.2

注意2:脚本的目的是在一个循环中,直到脚本创建最后一列,在这种情况下,最后一列是V3。但实际上它可能会达到 V800 或更高

然后在完成此操作后,在不改变输出的情况下降低结果,结果是:

  Date           data    V1     V2      V3
  2020-01-01      49.5   NA     NA      NA
  2020-02-01      49.7   49.6   NA      NA
  2020-03-14      48.5   49.1   49.35   NA
  2020-05-02      50.2   49.35  49.225  49.2875

注意:该函数可以很好地计算 V1 中的 P50,这很好,但它会在 V2、V3 等下丢球。

【问题讨论】:

  • 没有唯一的方法来计算分位数,这件事相当复杂。 R 支持 9 种不同的算法。多年来,Excel 改变了算法。您可以通过使用 type 参数来决定 R 使用哪种算法。你试过吗?我的意思是,这将是我在编写自己的算法之前的第一选择。

标签: r


【解决方案1】:

计算百分位数(或更一般地,分位数)并不像乍看起来那么容易。这样做的方法有很多很多,主要与如何处理关系有关。你确定你正在按照你想要的方式处理关系吗? R 的quantile 和 Excel 的方法之间的答案差异可能是它们处理关系的方式。 [R 在线帮助提供了 9 种不同的算法。]

我认为你的第一行有一个错字。我认为您应该说“我已经尝试使用 quantile 函数,但它并没有达到 的预期。”。如果quantile() 真的有问题,我想它现在可能已经被发现了......

【讨论】:

    【解决方案2】:

    我会在这里使用for 循环,因为每次迭代都会更新起始集。

    res <- NULL
    res[[1]] <- dat$data
    
    for (i in 2:4) {
      res[[i]] <- mapply(function(y) 
        quantile(res[[i - 1]][y], .5),
        Map(function(x) x:length(res[[i - 1]]), 1:(length(res[[i - 1]]) - 1)))
    }
    sapply(res, `length<-`, 4)
    #      [,1]  [,2]   [,3]    [,4]
    # [1,] 49.5 49.60 49.600 49.5625
    # [2,] 49.7 49.70 49.525      NA
    # [3,] 48.5 49.35     NA      NA
    # [4,] 50.2    NA     NA      NA
    

    但是,根据您提供的逻辑,我得到了不同的结果。


    数据:

    dat <- read.table(header=T, text='Date           data
    2020-01-01      49.5
    2020-02-01      49.7
    2020-03-14      48.5
    2020-05-02      50.2')
    

    【讨论】:

    • 我试过这个,但由于某种原因,我得到一个“'closure' 类型的对象不是子集的”我尝试使用 as.vector 更改数据,以确保它不是矢量问题,但不是运气。
    • @Island868 抱歉,缺少一行,res 必须初始化,请参阅更新后的答案。
    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 2014-02-08
    • 2011-01-25
    • 2021-07-25
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多