Выберите процент строк для каждой группы и рассчитайте статистику для определенного столбца

#r #dplyr

#r #dplyr

Вопрос:

У меня есть набор данных:

 value lt;- c(3,4,5,4,3,4,5,4,3,4,3,4,6,5,4,5,6,7,5,4,6,4,6,3,2,6,7,4,7,8,5,6,7,5,5,7,8,7,45,3,4,3,4,6,4,3,2,1,2,3,4) Sub lt;- c(rep("sub1", 10), rep("sub2",25), rep("sub3", 16))  dat lt;-as.data.frame(cbind(Sub, value))  

Это всего лишь пример, но он полезен, чтобы дать вам представление о моих целях.

Что мне нужно сделать, так это:

  1. Чтобы взять первые 10, 20,30, 40,50,60, 70,80,90,100% значений каждого подраздела e, вычислите статистику, такую как среднее или максимальное значение и так далее.
  2. Чтобы создать фрейм данных, подобный этому:
     p10 p20 p30 p40 p50 p60 p70 p80 p90 p100  

    Под1
    Суб2

    SUB…

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

 subset_percent lt;- function(x, start=0, end=100) {  stopifnot(  is.numeric(start), is.numeric(end),  start lt; end, start gt;= 0, end lt;= 100  )  nr lt;- nrow(x)  rows lt;- 1:nr  srt lt;- ceiling(start*nr/100)  end lt;-floor(end*nr/100)  x[srt:end,] }  

Мое намерение состояло в том, чтобы использовать dplyr для применения этой функции к каждой группе:

 newdat lt;- dat %gt;%   group_by(Sub) %gt;%   summarise( p10 = mean(subset_percent(dat,0,10)$value), p20 = mean(subset_percent(dat,0,20)$value), p30 = mean(subset_percent(dat,0,30)$value), p40 = mean(subset_percent(dat,0,40)$value), p50 = mean(subset_percent(dat,0,50)$value), p60 = mean(subset_percent(dat,0,60)$value), p70 = mean(subset_percent(dat,0,70)$value), p80 = mean(subset_percent(dat,0,80)$value), p90 = mean(subset_percent(dat,0,90)$value), p100 = mean(subset_percent(dat,0,100)$value))  

Однако вывод был неверным, потому что я получил этот ошибочный результат:

 Sub p10 p20 p30 p40 p50 p60 p70 p80 p90 p100  lt;chrgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; lt;dblgt; 1 sub1 3.8 3.9 4.07 4.4 4.36 4.7 4.83 5.98 5.78 5.39 2 sub2 3.8 3.9 4.07 4.4 4.36 4.7 4.83 5.98 5.78 5.39 3 sub3 3.8 3.9 4.07 4.4 4.36 4.7 4.83 5.98 5.78 5.39    

Ответ №1:

Вы можете использовать cut для разделения данных и использования quantile как breaks внутри каждого Sub. Calculate среднего значения в каждой группе и получения данных в широком формате.

 library(dplyr) library(tidyr)  dat %gt;%  group_by(Sub) %gt;%  mutate(group = cut(value, c(-Inf, unique(quantile(value, seq(0, 1, 0.1)))),   labels = FALSE) * 10) %gt;%  group_by(group, .add = TRUE) %gt;%  summarise(value = mean(value), .groups = 'drop') %gt;%  arrange(group) %gt;%  pivot_wider(names_from = group, values_from = value, names_prefix = 'p')  

Совет — Не делайте dat lt;- as.data.frame(cbind(...)) вместо dat lt;- data.frame(...) этого, то есть

 dat lt;- data.frame(Sub, value)  

Комментарии:

1. Спасибо, Ронак… к сожалению, я получил какой-то странный результат, используя ваш метод