Группировка подведение итогов по нескольким столбцам с подмножествами строк в R

#r #dataframe #tidyverse #tidyr

#r #фрейм данных #tidyverse #тидир

Вопрос:

Я пытаюсь найти чистое и tidy выражение для агрегирования статистики по нескольким столбцам, используя подмножества строк с group_by и summarise . Ниже приведен пример, решенный с помощью цикла.

 # example data dat lt;- data.frame(  method = rep(c("A", "B", "baseline"), 2),  id = rep(1:2, each = 3),  X = round(rnorm(6, 1, 0.2),3),  Y = round(runif(6, 1, 2),3) ) print(dat) #gt; method id X Y #gt; 1 A 1 0.859 1.003 #gt; 2 B 1 0.993 1.922 #gt; 3 baseline 1 1.401 1.959 #gt; 4 A 2 1.084 1.432 #gt; 5 B 2 1.083 1.883 #gt; 6 baseline 2 0.943 1.341  

Давайте рассмотрим A , B , baseline как названия методов, X , Y как критерии оценки и id как идентификатор повторных экспериментов. Затем мы хотим выяснить, насколько улучшились в смысле X и Y были достигнуты методом А и методом В. Улучшение измеряется как относительное уменьшение критериев оценки по сравнению с базовым методом.

 result lt;- dat[0,] for (i in unique(dat$id)) {  score_A lt;- dat[dat$id == i amp; dat$method == "A", c("X", "Y")]  score_B lt;- dat[dat$id == i amp; dat$method == "B", c("X", "Y")]  score_baseline lt;- dat[dat$id == i amp; dat$method == "baseline", c("X", "Y")]    result lt;- rbind(  result,  cbind(  data.frame(method = c("A", "B")),  rbind(  (score_baseline - score_A) / score_baseline,  (score_baseline - score_B) / score_baseline  )  )  ) } print(result) #gt; method X Y #gt; 3 A 0.3868665 0.48800408 #gt; 31 B 0.2912206 0.01888719 #gt; 6 A -0.1495228 -0.06785981 #gt; 61 B -0.1484624 -0.40417599  

Теперь я хотел бы получить более tidy подробное решение для приведенного выше результата.

Ответ №1:

Используя across вы могли бы сделать:

Примечание: При использовании случайных данных вы должны использовать set.seed . По этой причине мои случайные данные отличаются от предоставленных вами.

 library(dplyr)  dat %gt;%  group_by(id) %gt;%  mutate(across(c(X, Y), ~ (.x[method == "baseline"] - .x) / .x[method == "baseline"])) %gt;%  ungroup() %gt;%  filter(!method == "baseline") #gt; # A tibble: 4 × 4 #gt; method id X Y #gt; lt;chrgt; lt;intgt; lt;dblgt; lt;dblgt; #gt; 1 A 1 0.323 -0.521 #gt; 2 B 1 0.273 -0.426 #gt; 3 A 2 0.245 -0.823 #gt; 4 B 2 0.236 -0.196  

данные

 set.seed(123)  dat lt;- data.frame(  method = rep(c("A", "B", "baseline"), 2),  id = rep(1:2, each = 3),  X = round(rnorm(6, 1, 0.2), 3),  Y = round(runif(6, 1, 2), 3) )