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