функция цикла, которая берет элементы из двух матриц и выполняет вычисление - PullRequest
0 голосов
/ 31 октября 2018

У меня есть две матрицы. Одна представляет собой матрицу 36x6, а другая - 6x6.

Я хотел бы эффективно выполнить этот расчет:

enter image description here

Матрица 36x6 содержит элементы phij, а матрица 6x6 содержит элементы pij.

Две буквы после тире в каждых 6 именах строк матрицы 36x6, например. имя первой строки: «Aa- Aa », в том же порядке, что и имена строк матрицы 6x6.

Моя матрица 36x6 выглядит следующим образом:

                   Aa           A         Baa         Ba          B        Caa
  Aa-Aa   0.333333333 0.000000000 0.333333333 0.00000000 0.33333333 0.00000000
  A-Aa    0.250000000 0.250000000 0.000000000 0.50000000 0.00000000 0.00000000
  Baa-Aa  0.000000000 0.400000000 0.000000000 0.40000000 0.20000000 0.00000000
  Ba-Aa   0.000000000 0.333333333 0.333333333 0.00000000 0.33333333 0.00000000
  B-Aa    0.000000000 0.142857143 0.142857143 0.42857143 0.28571429 0.00000000
  Caa-Aa  0.250000000 0.000000000 0.250000000 0.25000000 0.00000000 0.25000000
  Aa-A    0.125000000 0.750000000 0.125000000 0.00000000 0.00000000 0.00000000
  A-A     0.055555556 0.222222222 0.222222222 0.33333333 0.11111111 0.05555556
  Baa-A   0.045454545 0.272727273 0.318181818 0.31818182 0.04545455 0.00000000
  Ba-A    0.062500000 0.125000000 0.437500000 0.31250000 0.06250000 0.00000000
  B-A     0.000000000 0.181818182 0.181818182 0.36363636 0.00000000 0.27272727
  Caa-A   0.000000000 0.125000000 0.125000000 0.37500000 0.25000000 0.12500000
  Aa-Baa  0.000000000 0.250000000 0.125000000 0.50000000 0.12500000 0.00000000
  A-Baa   0.040000000 0.120000000 0.440000000 0.16000000 0.24000000 0.00000000
 Baa-Baa 0.011764706 0.094117647 0.376470588 0.29411765 0.15294118 0.07058824
 Ba-Baa  0.013888889 0.097222222 0.236111111 0.27777778 0.27777778 0.09722222
 B-Baa   0.000000000 0.000000000 0.347826087 0.10869565 0.43478261 0.10869565
 Caa-Baa 0.052631579 0.052631579 0.210526316 0.26315789 0.26315789 0.15789474
 Aa-Ba   0.000000000 0.000000000 0.111111111 0.66666667 0.11111111 0.11111111
 A-Ba    0.000000000 0.040000000 0.160000000 0.44000000 0.32000000 0.04000000
 Baa-Ba  0.015384615 0.061538462 0.292307692 0.27692308 0.20000000 0.15384615
 Ba-Ba   0.007194245 0.028776978 0.208633094 0.35251799 0.28057554 0.12230216
 B-Ba    0.000000000 0.033783784 0.087837838 0.28378378 0.37837838 0.21621622
 Caa-Ba  0.012987013 0.012987013 0.077922078 0.28571429 0.32467532 0.28571429
 Aa-B    0.000000000 0.000000000 0.000000000 0.60000000 0.40000000 0.00000000
 A-B     0.000000000 0.166666667 0.000000000 0.33333333 0.50000000 0.00000000
 Baa-B   0.046153846 0.030769231 0.076923077 0.32307692 0.26153846 0.26153846
 Ba-B    0.000000000 0.006802721 0.068027211 0.25850340 0.40816327 0.25850340
 B-B     0.005449591 0.008174387 0.051771117 0.12261580 0.49318801 0.31880109
 Caa-B   0.007380074 0.018450185 0.051660517 0.14022140 0.38745387 0.39483395
 Aa-Caa  0.000000000 0.000000000 0.000000000 0.00000000 0.00000000 1.00000000
 A-Caa   0.000000000 0.200000000 0.000000000 0.00000000 0.60000000 0.20000000
 Baa-Caa 0.000000000 0.000000000 0.045454545 0.27272727 0.40909091 0.27272727
 Ba-Caa  0.000000000 0.023809524 0.059523810 0.13095238 0.32142857 0.46428571
 B-Caa   0.010600707 0.010600707 0.028268551 0.10247350 0.32155477 0.52650177
 Caa-Caa 0.001811594 0.003623188 0.009057971 0.05978261 0.26992754 0.65579710

И матрица 6x6 выглядит так:

                                  Period 2 Short Ratings
  Period 1 Short Ratings          Aa           A        Baa         Ba          B        Caa
                     Aa  0.088235294 0.235294118 0.23529412 0.26470588 0.14705882 0.02941176
                     A   0.044444444 0.233333333 0.30000000 0.30000000 0.06666667 0.05555556
                     Baa 0.017985612 0.082733813 0.31654676 0.24820144 0.25179856 0.08273381
                     Ba  0.006048387 0.034274194 0.15322581 0.31451613 0.31048387 0.18145161
                     B   0.007675439 0.014254386 0.05592105 0.16995614 0.42872807 0.32346491
                     Caa 0.004081633 0.008163265 0.02040816 0.08163265 0.29693878 0.58877551
    attr(,"class")
    [1] "matrix"

nhi - сумма строк, соответствующая элементам в phij матрицы 36x6.

Они взяты из этой матрицы:

          Aa A Baa Ba   B Caa
      A-A  1 4   4  6   2   1
     A-Aa  1 1   0  2   0   0
      A-B  0 1   0  2   3   0
     A-Ba  0 1   4 11   8   1
    A-Baa  1 3  11  4   6   0
    A-Caa  0 1   0  0   3   1
     Aa-A  1 6   1  0   0   0
    Aa-Aa  1 0   1  0   1   0
     Aa-B  0 0   0  3   2   0
    Aa-Ba  0 0   1  6   1   1
   Aa-Baa  0 2   1  4   1   0
   Aa-Caa  0 0   0  0   0   1
      B-A  0 2   2  4   0   3
     B-Aa  0 1   1  3   2   0
      B-B  2 3  19 45 181 117
     B-Ba  0 5  13 42  56  32
    B-Baa  0 0  16  5  20   5
    B-Caa  3 3   8 29  91 149
     Ba-A  1 2   7  5   1   0
    Ba-Aa  0 1   1  0   1   0
     Ba-B  0 1  10 38  60  38
    Ba-Ba  1 4  29 49  39  17
   Ba-Baa  1 7  17 20  20   7
   Ba-Caa  0 2   5 11  27  39
    Baa-A  1 6   7  7   1   0
   Baa-Aa  0 2   0  2   1   0
    Baa-B  3 2   5 21  17  17
   Baa-Ba  1 4  19 18  13  10
  Baa-Baa  1 8  32 25  13   6
  Baa-Caa  0 0   1  6   9   6
    Caa-A  0 1   1  3   2   1
   Caa-Aa  1 0   1  1   0   1
    Caa-B  2 5  14 38 105 107
   Caa-Ba  1 1   6 22  25  22
  Caa-Baa  1 1   4  5   5   3
  Caa-Caa  1 2   5 33 149 362

Я хочу, чтобы цикл циклически проходил через первые 6 элементов столбца j в матрице 36x6, и для каждого элемента он вычитал первый элемент в матрице 6x6, возводил в квадрат результат, делил на первый элемент в матрице 6x6, умножает результат на сумму строки строки текущего элемента в матрице 36x6 и временно сохраняет 6 результатов? Затем цикл перемещается вниз по столбцу к следующим 6 элементам строки j в 36x6 и повторяет шаги. Когда это будет сделано с первым столбцом, я хочу, чтобы он перешел к столбцу j + 1 в матрицах 36x6 и 6x6 и повторил упомянутые шаги.

1 Ответ

0 голосов
/ 31 октября 2018

Вот подход, использующий tidyverse, основанный на прочтении вашего вопроса. Это должно вычисляться очень быстро, поскольку соединения с базой данных и векторизованные вычисления будут работать быстрее, чем циклы. И я думаю, что и этот способ более читабелен.

Кстати, мне непонятно, как соотносится последняя таблица, поскольку в верхней формуле нет упоминания о nhi. Но я надеюсь, что это точно вычислит первую часть уравнения и даст представление о том, как закончить.

Сначала я готовлю таблицы длинного формата Phij, Pij и Phi (см. Внизу). Затем я присоединяюсь к ним и делаю математику, за которой легче следить, когда элементы находятся рядом.

library(tidyverse)
output <- Phij %>%
  # Attach matching columns from Pij and Phi
  left_join(Pij, by = c("i", "j")) %>%
  left_join(Phi, by = c("h", "i")) %>%

  # Calculate first term as in equation
  mutate(first_term = ((Phij - Pij)^2) * Phi)

Вывод: это в длинном формате, но его можно изменить, используя spread

> head(output)
    h  i  j      Phij        Pij Phi  first_term
1  Aa Aa Aa 0.3333333 0.08823529   1 0.060073048
2   A Aa Aa 0.2500000 0.08823529   1 0.026167820
3 Baa Aa Aa 0.0000000 0.08823529   1 0.007785467
4  Ba Aa Aa 0.0000000 0.08823529   1 0.007785467
5   B Aa Aa 0.0000000 0.08823529   1 0.007785467
6 Caa Aa Aa 0.2500000 0.08823529   1 0.026167820

Подготовка длинных таблиц: я не уверен на 100%, правильно ли я интерпретирую координаты ваших матриц, но в таком случае это легко исправить.

1) Чтобы сделать Phij, я читаю в матрице таблицу (обратите внимание, я добавил «hi» в качестве имени первого столбца), разбиваю имена строк на h и i и собираю имена столбцов в новый столбец j.

library(tidyverse)
Phij <- read.table(stringsAsFactors = F, header = T, text = "
     hi            Aa           A         Baa         Ba          B        Caa
  Aa-Aa   0.333333333 0.000000000 0.333333333 0.00000000 0.33333333 0.00000000
  A-Aa    0.250000000 0.250000000 0.000000000 0.50000000 0.00000000 0.00000000
  Baa-Aa  0.000000000 0.400000000 0.000000000 0.40000000 0.20000000 0.00000000
  Ba-Aa   0.000000000 0.333333333 0.333333333 0.00000000 0.33333333 0.00000000
  B-Aa    0.000000000 0.142857143 0.142857143 0.42857143 0.28571429 0.00000000
  Caa-Aa  0.250000000 0.000000000 0.250000000 0.25000000 0.00000000 0.25000000
  Aa-A    0.125000000 0.750000000 0.125000000 0.00000000 0.00000000 0.00000000
  A-A     0.055555556 0.222222222 0.222222222 0.33333333 0.11111111 0.05555556
  Baa-A   0.045454545 0.272727273 0.318181818 0.31818182 0.04545455 0.00000000
  Ba-A    0.062500000 0.125000000 0.437500000 0.31250000 0.06250000 0.00000000
  B-A     0.000000000 0.181818182 0.181818182 0.36363636 0.00000000 0.27272727
  Caa-A   0.000000000 0.125000000 0.125000000 0.37500000 0.25000000 0.12500000
  Aa-Baa  0.000000000 0.250000000 0.125000000 0.50000000 0.12500000 0.00000000
  A-Baa   0.040000000 0.120000000 0.440000000 0.16000000 0.24000000 0.00000000
 Baa-Baa 0.011764706 0.094117647 0.376470588 0.29411765 0.15294118 0.07058824
 Ba-Baa  0.013888889 0.097222222 0.236111111 0.27777778 0.27777778 0.09722222
 B-Baa   0.000000000 0.000000000 0.347826087 0.10869565 0.43478261 0.10869565
 Caa-Baa 0.052631579 0.052631579 0.210526316 0.26315789 0.26315789 0.15789474
 Aa-Ba   0.000000000 0.000000000 0.111111111 0.66666667 0.11111111 0.11111111
 A-Ba    0.000000000 0.040000000 0.160000000 0.44000000 0.32000000 0.04000000
 Baa-Ba  0.015384615 0.061538462 0.292307692 0.27692308 0.20000000 0.15384615
 Ba-Ba   0.007194245 0.028776978 0.208633094 0.35251799 0.28057554 0.12230216
 B-Ba    0.000000000 0.033783784 0.087837838 0.28378378 0.37837838 0.21621622
 Caa-Ba  0.012987013 0.012987013 0.077922078 0.28571429 0.32467532 0.28571429
 Aa-B    0.000000000 0.000000000 0.000000000 0.60000000 0.40000000 0.00000000
 A-B     0.000000000 0.166666667 0.000000000 0.33333333 0.50000000 0.00000000
 Baa-B   0.046153846 0.030769231 0.076923077 0.32307692 0.26153846 0.26153846
 Ba-B    0.000000000 0.006802721 0.068027211 0.25850340 0.40816327 0.25850340
 B-B     0.005449591 0.008174387 0.051771117 0.12261580 0.49318801 0.31880109
 Caa-B   0.007380074 0.018450185 0.051660517 0.14022140 0.38745387 0.39483395
 Aa-Caa  0.000000000 0.000000000 0.000000000 0.00000000 0.00000000 1.00000000
 A-Caa   0.000000000 0.200000000 0.000000000 0.00000000 0.60000000 0.20000000
 Baa-Caa 0.000000000 0.000000000 0.045454545 0.27272727 0.40909091 0.27272727
 Ba-Caa  0.000000000 0.023809524 0.059523810 0.13095238 0.32142857 0.46428571
 B-Caa   0.010600707 0.010600707 0.028268551 0.10247350 0.32155477 0.52650177
 Caa-Caa 0.001811594 0.003623188 0.009057971 0.05978261 0.26992754 0.65579710") %>%

separate(hi, into = c("h", "i"), sep = "-") %>%
  gather(j, Phij, Aa:Caa)

2) Аналогично для Pij:

Pij <- read.table(stringsAsFactors = F, header = T, text = "
i        Aa           A        Baa         Ba          B        Caa
Aa  0.088235294 0.235294118 0.23529412 0.26470588 0.14705882 0.02941176
A   0.044444444 0.233333333 0.30000000 0.30000000 0.06666667 0.05555556
Baa 0.017985612 0.082733813 0.31654676 0.24820144 0.25179856 0.08273381
Ba  0.006048387 0.034274194 0.15322581 0.31451613 0.31048387 0.18145161
B   0.007675439 0.014254386 0.05592105 0.16995614 0.42872807 0.32346491
Caa 0.004081633 0.008163265 0.02040816 0.08163265 0.29693878 0.58877551") %>%
  gather(j, Pij, Aa:Caa)

3) Я сделал Phi, суммируя каждую строку (т. Е. H / i комбинацию) Phij:

# Note, these are all 1, but maybe good to include to see typos in source
Phi <- Phij %>%
  group_by(h,i) %>%
  summarize(Phi= sum(Phij)) %>%
  ungroup()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...