В попытке избежать вложения для циклов 6-7 раз, я пытаюсь использовать lapply, чтобы найти долю случайно нарисованных значений (которые объединены определенным образом), которые превышают некоторые произвольные значения порогов. Проблема в том, что у меня есть несколько параметров, каждый из которых варьируется определенным количеством способов, и они, в свою очередь, влияют на то, как значения объединяются. Цель состоит в том, чтобы использовать результаты в ANOVA, чтобы увидеть, как изменение этих параметров способствует достижению этих пороговых значений. Однако я не понимаю, как это сделать. У меня есть ощущение, что анонимные функции могут быть полезны, но я не понимаю, как они работают с более чем одним параметром.
Я попытался максимально упростить код. Но опять же, есть так много параметров, которые должны быть включены.
trials = 10
data_means = c(0,1,2,3)
prior_samples = c(2, 8, 32)
data_SD = c(0.5, 1, 2)
thresholds = c(10, 30, 80)
Идея состоит в том, что есть два распределения, data и предыдущие , из которых я черпаю значения. Я всегда рисую один из данных, но я рисую образец (см. prior_samples
) значений из предыдущего распределения. Существует четыре различных значения, которые определяют среднее значение распределения данных (см. data_means
), но значения извлекаются одинаковое количество раз (определяемое trials
) из каждой из этих четырех «версий» распределения данных. Затем они помещаются во вложенные списки:
set.seed(123)
data_list = list()
for (nMean in data_means){ #the data values
for (nTrial in 1:trials){
data_list[[paste(nMean, sep="_")]][[paste(nTrial, sep="_")]] = rnorm(1, nMean, 1)
}
}
prior_list = list()
for (nSamples in prior_samples){ #the prior values
for (nTrial in 1:trials){
prior_list[[paste(nSamples, sep="_")]][[paste(nTrial, sep="_")]] = rnorm(nSamples, 0, 1)
}
}
Затем я создаю другой список для предыдущих значений, потому что я хочу вычислить средние значения и стандартные отклонения (SD) выборок предыдущих значений. Я включаю обычные SD, а также SD / 2 и SD * 2:
prior_SD = list("mean"=0, "standard_devations"=list("SD/2"=0, "SD"=0, "SD*2"=0))
prior_mean_SD = rep(list(prior_SD), trials)
prior_nested_list = list("2"=prior_mean_SD, "8"=prior_mean_SD, "32"=prior_mean_SD)
for (nSamples in 1:length(prior_samples)){
for (nTrial in 1:trials){
prior_nested_list[[nSamples]][[nTrial]][["mean"]]=mean(prior_list[[nSamples]][[nTrial]])
prior_nested_list[[nSamples]][[nTrial]][["standard_devations"]][["SD/2"]]=sum(sd(prior_list[[nSamples]][[nTrial]])/2)
prior_nested_list[[nSamples]][[nTrial]][["standard_devations"]][["SD"]]=sd(prior_list[[nSamples]][[nTrial]])
prior_nested_list[[nSamples]][[nTrial]][["standard_devations"]][["SD*2"]]=sum(sd(prior_list[[nSamples]][[nTrial]])*2)
}
}
Затем я объединяю значения из списка данных и последнего списка, используя list.zip
из rlist
:
library(rlist)
dataMean0 = list.zip(dMean0=data_list[["0"]], pSample2=prior_nested_list[["2"]],
pSample8=prior_nested_list[["8"]], pSample32=prior_nested_list[["32"]])
dataMean1 = list.zip(dMean1=data_list[["1"]], pSample2=prior_nested_list[["2"]],
pSample8=prior_nested_list[["8"]], pSample32=prior_nested_list[["32"]])
dataMean2 = list.zip(dMean2=data_list[["2"]], pSample2=prior_nested_list[["2"]],
pSample8=prior_nested_list[["8"]], pSample32=prior_nested_list[["32"]])
dataMean3 = list.zip(dMean3=data_list[["3"]], pSample2=prior_nested_list[["2"]],
pSample8=prior_nested_list[["8"]], pSample32=prior_nested_list[["32"]])
all_values = list(mean_difference0=dataMean0, mean_difference1=dataMean1,
mean_difference2=dataMean2, mean_difference3=dataMean3)
Теперь самое сложное. Я объединяю значения данных и предыдущие значения в all_values
, используя эту пользовательскую функцию для расхождения Кульбака-Лейблера. Как видите, существует 6 различных параметров:
mean_diff
относится к средствам распределения данных (data_means
). Он называется mean_diff
, поскольку он относится к разнице в среднем между предыдущим распределением (которое всегда равно 0) и распределением данных (которое может быть 0, 1, 2 или 3). trial
относится к trials
, pSample
относится к числу выборок, взятых из предыдущего распределения (prior_samples
) p_SD
относится к расчетам SD на основе предыдущие выборки (обычные SD, SD / 2, SD * 2) data_SD
относятся к SD распределения данных, определяемого как data_SD
threshold
относится к thresholds
Функция дивергенции Кульбака-Лейблера:
kld = function(mean_diff, trial, pSample, p_SD, data_SD, threshold){
prior_mean = all_values[[mean_diff]][[trial]][[pSample]][["mean"]]
data_mean = all_values[[mean_diff]][[trial]][["mean"]]
prior_SD = all_values[[mean_diff]][[trial]][[pSample]][["standard_devations"]][[p_SD]]
posterior_SD = sqrt(1/(1/
((all_values[[mean_diff]][[trial]][[pSample]][["standard_devations"]][[p_SD]]
*all_values[[mean_diff]][[trial]][[pSample]][["standard_devations"]][[p_SD]]))
+1/(data_SD*data_SD)))
length(
which(
(log(prior_SD/posterior_SD) +
(((posterior_SD*posterior_SD) +
(prior_mean -
(((data_SD*data_SD))/
((data_SD*data_SD)+(prior_SD*prior_SD))*prior_mean +
((prior_SD*prior_SD))/
((data_SD*data_SD)+(prior_SD*prior_SD))*data_mean))^2)
/(2*(prior_SD*prior_SD)))-0.5
+
log(posterior_SD/prior_SD) +
((((prior_SD*prior_SD)) +
(prior_mean -
(((data_SD*data_SD))/
((data_SD*data_SD)+(prior_SD*prior_SD))*prior_mean +
((prior_SD*prior_SD))/
((data_SD*data_SD)+(prior_SD*prior_SD))*data_mean))^2)
/(2*(posterior_SD*posterior_SD)))-0.5
)>=threshold))/trials
}
Поэтому вопрос заключается в том, как можно использовать lapply в списке со всеми значениями (all_values
) при использовании все разные комбинации из шести параметров, которые включены? Данные, которые я хочу получить, представляют собой пропорции значений (в процентах от trials
), которые превышают thresholds
во всех комбинациях параметров.
Я не могу найти необходимую информацию, поэтому любые советы будут оценены.