У меня есть кадр данных из нескольких пар оценок и дисперсий для нескольких параметров модели, каждый из которых находится внутри одного из нескольких разделов. Здесь функция, которая генерирует иллюстративный образец:
samplerats <- function(){
set.seed(310366)
d = data.frame(section=c(rep("S1",10),rep("S2",10),rep("S3",5)))
nr = nrow(d)
for(i in 1:5){
d[[paste0("est_v",i)]] = rnorm(nr)
d[[paste0("var_v",i)]] = runif(nr)
}
d
}
и вот начало того, что вы получаете:
> d=samplerats()
> head(d)
section est_v1 var_v1 est_v2 var_v2 est_v3 var_v3
1 S1 0.3893008 0.1620882 -1.1915391 0.15439565 0.62022284 0.5487519
2 S1 0.8221099 0.3280630 0.7729817 0.14810283 -1.11337584 0.9947342
3 S1 0.8023230 0.1862810 -1.5285389 0.85648574 -1.74666907 0.4267944
4 S1 -0.2252865 0.5660111 -0.4348341 0.53013027 0.01823185 0.1379821
5 S1 -0.9475335 0.7904085 -1.0882961 0.40567780 1.69607397 0.3450983
6 S1 0.4415259 0.2969032 0.9200723 0.08754107 0.57010457 0.7579002
[with another two variables and 25 rows in total]
Задача состоит в том, чтобы вычислить отношение дисперсии оценок для каждого параметра со средним значением дисперсии для каждого параметра, сгруппированным по разделу.
Так, например, для переменной v1 грубо просто получить номера:
> d %>% group_by(section) %>% summarise(var(est_v1)/mean(var_v1))
Source: local data frame [3 x 2]
section var(est_v1)/mean(var_v1)
1 S1 0.5874458
2 S2 2.4449153
3 S3 2.8621725
Это дает нам ответ для v1
, нам просто нужно повторить для всех других переменных. Обратите внимание, что имена столбцов: est_
или var_
, за которым следует имя переменной, которое может быть alpha
или g2
или какой-либо другой буквенно-цифровой символ.
Конечно, у меня есть ужасное решение:
ratit <- function(d){
isVAR <- function(s){stringr::str_sub(s,1,4)=="var_"}
spreads = reshape2::melt(d) %>% mutate(isVAR=isVAR(variable), Variable = str_replace(variable,"^.*_",""))
vout = spreads %>% group_by(Variable, section, isVAR) %>% summarise(Z=if(isVAR(variable[1])){mean(value)}else{var(value)})
ratios = vout %>% group_by(section, Variable) %>% summarise(Vratio = Z[1]/Z[2]) %>% dcast(section ~ Variable)
ratios
}
который дает:
> ratit(d)
Using section as id variables
Using Vratio as value column: use value.var to override.
section v1 v2 v3 v4 v5
1 S1 0.5874458 3.504169 3.676488 1.1716684 1.742021
2 S2 2.4449153 1.177326 1.106337 1.0700636 3.263149
3 S3 2.8621725 2.216099 3.846062 0.7777452 2.122726
где вы можете видеть, что первый столбец совпадает с примером v1
-only ранее. Но yuck.
Если я могу расплавить, бросить, dplyr или иначе вывести его в этот формат:
est var section variable
1 0.3893008 0.1620882 S1 v1
2 0.8221099 0.3280630 S1 v1
3 0.8023230 0.1862810 S1 v1
4 -0.2252865 0.5660111 S1 v1
5 -0.9475335 0.7904085 S1 v1
6 0.4415259 0.2969032 S1 v1
то его тривиальное - dd %>% group_by(section, variable) %>% summarise(rat=var(est)/mean(var)) %>% spread(variable, rat)
Но этот шаг ускользает от меня...
Приветствуем приветственные решения, используя что-либо, включая базовые R, dplyr, tidyr, data.table и т.д.