首页 > 解决方案 > 创建数据集的百分位数

问题描述

我试过使用分位数功能,但它没有按预期工作。

我也使用了新功能

 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 计算

V1计算

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

和 V2 计算

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

解决方案


我会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')

推荐阅读