在 R 中按组将分位数与单个数字进行比较

Compare the quantile against a single number by groups in R

我有两个数据框:第一个包含 product_id 和该产品许多订单的周期时间,另一个数据框包含每个产品的标准周期时间。我想要实现的是查看它们各自的标准周期时间与实际周期时间分布的比较。更具体地说,对于产品 A,历史周期时间为:

cycletime_for_A <- rnorm(n = 100,mean = 5,sd = 2)

standard_ct_for_A <- 8

percentile_of_a <- ecdf(cycletime_for_A)

percentile_of_a(standard_ct_for_A)

然后我得到 0.95 的结果,这意味着在 95% 的情况下,实际循环时间比标准循环时间短。

但是,我有数以千计的不同标准周期时间的不同产品,我如何通过组来完成同样的事情?如果可能的话,我的目标是采用 tidyverse 方法。

一个最小的示例数据集如下:

product_cycle_time <- data.frame(
  product_id = rep(c("A","B","C"),100),
  cycle_time = round(runif(n = 300,min = 1,max = 100))
)

standard_cycle_time <- data.frame(
  product_id=c("A","B","C"),
  std_cycle_time=c(10,20,15)
)

试试这个。基本思路:根据产品id拆分df,然后使用map2对每个产品进行计算。

library(dplyr)
library(purrr)

set.seed(42)

product_cycle_time <- data.frame(
  product_id = rep(c("A","B","C"),100),
  cycle_time = round(runif(n = 300,min = 1,max = 100))
) %>% 
  split(.$product_id)

standard_cycle_time <- data.frame(
  product_id=c("A","B","C"),
  std_cycle_time=c(10,20,15)
)%>% 
  split(.$product_id)

purrr::map2(product_cycle_time, standard_cycle_time, ~ ecdf(.x$cycle_time)(.y$std_cycle_time))
#> $A
#> [1] 0.1
#> 
#> $B
#> [1] 0.19
#> 
#> $C
#> [1] 0.15

reprex package (v0.3.0)

于 2020 年 3 月 27 日创建

为了更方便,您可以先merge数据框,

dat <- merge(product_cycle_time, standard_cycle_time, all=TRUE)

然后,使用 mapply:

with(dat, mapply(function(x, y) ecdf(x)(y), split(cycle_time, product_id), 
                 unique(std_cycle_time)))
#    A    B    C 
# 0.10 0.19 0.15 

如果您想要列表而不是向量,请使用 Map 而不是 mapply

,使用by

by(dat, dat$product_id, function(x) ecdf(x$cycle_time)(el(x$std_cycle_time)))
# dat$product_id: A
# [1] 0.1
# ------------------------------------------------------------------- 
# dat$product_id: B
# [1] 0.19
# ------------------------------------------------------------------- 
# dat$product_id: C
# [1] 0.15

数据:

set.seed(42)
product_cycle_time <- data.frame(
  product_id=LETTERS[1:3],
  cycle_time=round(runif(300,1,100))
)
standard_cycle_time <- data.frame(
  product_id=LETTERS[1:3],
  std_cycle_time=c(10,20,15)
)