循环函数,从两个矩阵中获取元素并执行计算

时间:2018-10-31 16:59:47

标签: r loops matrix

我有两个矩阵。一个是36x6矩阵,另一个是6x6。

我想有效地运行此计算:

enter image description here

36x6矩阵包含phij元素,而6x6矩阵包含pij元素。

36x6矩阵的每6行名称中破折号后的两个字母,例如第一行名称:“ 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是对应于36x6矩阵phij中元素的行总和。

它们来自此矩阵:

          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

我希望循环在36x6矩阵中的j列的前6个元素之间循环,并为每个元素减去6x6矩阵中的第一个元素,将结果平方,再除以6x6矩阵中的第一个元素,将结果乘以36x6矩阵中当前元素行的行总和,并临时存储6个结果?然后循环将列向下移动到36x6中第j行的下6个元素,并重复上述步骤。当第一列完成后,我希望它进入36x6和6x6矩阵中的j + 1列,并重复上述步骤。

1 个答案:

答案 0 :(得分:0)

以下是根据我对您的问题的理解,使用tidyverse的一种方法。由于数据库联接和矢量化计算的工作速度将比循环快,因此该计算应该非常快。而且我认为这种计算方式也更易读。

顺便说一句,我不清楚最后一张表格的关系,因为最上面的公式中没有提到nhi。但是我希望它能忠实地计算出方程式的第一部分,并应该给出一个如何完成方程的想法。

首先,我准备长格式表PhijPijPhi(请参阅底部)。然后,我加入他们并进行数学运算,当元素相邻时,更容易理解。

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”),将行名称分为hi ,然后将列名称收集到新列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()