Как изменить несколько параметров с помощью lapply в R - PullRequest
0 голосов
/ 06 апреля 2020

В попытке избежать вложения для циклов 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 во всех комбинациях параметров.

Я не могу найти необходимую информацию, поэтому любые советы будут оценены.

...