Создать таблицу со значениями из графа ecdf - PullRequest
0 голосов
/ 04 февраля 2020

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

#Data
data(mtcars)

#Sort by mpg
mtcars <- mtcars[order(mtcars$mpg),]

#Make arbitrary ranking variable based on mpg
mtcars <- mtcars %>% mutate(Rank = dense_rank(mpg))

#Make variable for percent picked
mtcars <- mutate(mtcars, Percent_Picked = Rank/max(mtcars$Rank))

#Make cyl categorical
mtcars$cyl<-cut(mtcars$cyl, c(3,5,7,9), right=FALSE, labels=c(4,6,8))

#Make the graph
ggplot(mtcars, aes(Percent_Picked, color = cyl)) + 
  stat_ecdf(size=1) + 
  scale_x_continuous(labels = scales::percent) +
  scale_y_continuous(labels = scales::percent)

, который создает этот сюжет (я не был здесь достаточно долго, чтобы публиковать изображения, поэтому ссылка).

Я хочу создать таблицу для значений каждого из типов цилиндров, когда общий Percent_Picked составляет 25%, 50% и 75%. Итак, то, что показывает, что 4-циландер равен 0%, 6 - около 28%, а 8 - около 85%.

Расчет квантилей по группам не дает мне того, что я хочу (он показывает процент все цилиндры были выбраны, когда было выбрано 25%, 50% и 75% определенного типа цилиндров). (Например, предложения tbradley1013 в их блоге помогают только с квантилями для каждого конкретного цилиндра, а не с общим cdf для каждого цилиндра в данных квантилях для Percent_Picked.)

Любые выводы будут оценили!

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

Оглядываясь вокруг, я нашел этот вопрос . Ваш немного расширяет это, запрашивая групповые значения c ecdf, поэтому мы можем использовать функцию do в dplyr (, вот пример ]. Есть некоторые небольшого различия в значениях при сравнении между этой таблицей и значениями в вашем ggplot, и я не совсем уверен, почему это так. Может быть, просто набор данных mtcars несколько мал, так что если вы запустите его на большом наборе данных Я ожидал бы, что это будет ближе к фактическим значениям.


#Sort by mpg
mtcars <- mtcars[order(mtcars$mpg),]

#Make arbitrary ranking variable based on mpg
mtcars <- mtcars %>% mutate(Rank = dense_rank(mpg))

#Make variable for percent picked
mtcars <- mutate(mtcars, Percent_Picked = Rank/max(mtcars$Rank))

#Make cyl categorical
mtcars$cyl<-cut(mtcars$cyl, c(3,5,7,9), right=FALSE, labels=c(4,6,8))

#Make the graph
ggplot(mtcars, aes(Percent_Picked, color = cyl)) + 
  stat_ecdf(size=1) + 
  scale_x_continuous(labels = scales::percent) +
  scale_y_continuous(labels = scales::percent)


create_ecdf_vals <- function(vec){
  df <- data.frame(
    x = unique(vec),
    y = ecdf(vec)(unique(vec))*length(vec)
  ) %>%
    mutate(y = scale(y, center = min(y), scale = diff(range(y)))) %>%
    union_all(data.frame(x=c(0,1),
                         y=c(0,1))) # adding in max/mins
  return(df)
}

mt.ecdf <- mtcars %>%
  group_by(cyl) %>%
  do(create_ecdf_vals(.$Percent_Picked))


mt.ecdf %>%
  summarise(q25 = y[which.max(x[x<=0.25])],
            q50 = y[which.max(x[x<=0.5])],
            q75 = y[which.max(x[x<=0.75])])

ggplot(mt.ecdf,aes(x,y,color = cyl)) +
  geom_step()

~ EDIT ~
После некоторого изучения документов ggplot2 мы можем явно извлечь данные из график с использованием функции layer_data.

my.plt <- ggplot(mtcars, aes(Percent_Picked, color = cyl)) + 
  stat_ecdf(size=1) + 
  scale_x_continuous(labels = scales::percent) +
  scale_y_continuous(labels = scales::percent)

plt.data <- layer_data(my.plt) # magic happens here

# and here's the table you want
plt.data %>%
  group_by(group) %>%
  summarise(q25 = y[which.max(x[x<=0.25])],
            q50 = y[which.max(x[x<=0.5])],
            q75 = y[which.max(x[x<=0.75])])
0 голосов
/ 14 апреля 2020

Гораздо более короткий ответ, который я не могу поверить, что я не видел раньше. По сути, я просто делю количество строк, равное или меньше, чем .25, .5 и .75 на общее количество строк, для каждого цилиндра.

cyl.table<-mtcars %>%
  group_by(cyl) %>%
    summarise("25% Picked" = sum(Percent_Picked<=0.25)/(sum(Percent_Picked<=1)),
              "50% Picked" = sum(Percent_Picked<=0.5)/(sum(Percent_Picked<=1)),
              "75% Picked" = sum(Percent_Picked<=0.75)/(sum(Percent_Picked<=1)))
cyl.table
...