Сравните квантиль против одного числа по группам в R - PullRequest
0 голосов
/ 27 марта 2020

У меня есть два фрейма данных: первый содержит 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% вероятности фактическое время цикла меньше стандартного времени цикла.

Тем не менее, у меня есть тысячи различных продуктов с разным стандартным временем цикла. Как бы я смог выполнить то же самое с группами? Я стремлюсь к подходу, когда это возможно.

Минимальный примерный набор данных, как показано ниже:

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)
)

Ответы [ 2 ]

0 голосов
/ 27 марта 2020

Вы можете сначала 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)
)
0 голосов
/ 27 марта 2020

Попробуй это. Базовая c идея: разделите 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

Создано в 2020-03-27 пакетом представ. (v0.3.0)

...