R 将协方差矩阵转换为具有协方差变量的数据帧

R 将协方差矩阵转换为具有协方差变量的数据帧,r,matrix,reshape,data-manipulation,reshape2,R,Matrix,Reshape,Data Manipulation,Reshape2,矩阵cov_mat存储变量之间的协方差: a_plane a_boat a_train b_plane b_boat b_train c_plane c_boat c_train d_plane … a_plane 4.419 -0.583 0.446 0.018 -1.291 3.159 -0.954 0.488 3.111 1.100 a_boat -0.583 2.636 1.813 -1.511 -0.420 -

矩阵cov_mat存储变量之间的协方差:

        a_plane a_boat  a_train b_plane b_boat  b_train c_plane c_boat  c_train d_plane …
a_plane   4.419 -0.583    0.446  0.018  -1.291    3.159  -0.954  0.488    3.111   1.100 
a_boat   -0.583  2.636    1.813 -1.511  -0.420   -0.757   1.698  1.668    1.091   0.120 
a_train   0.446  1.813    2.668 -0.365  -0.183    1.040   1.347  1.813    0.806  -0.324 
b_plane   0.018 -1.511   -0.365  2.498   1.153    1.498  -0.465 -1.157   -0.775   0.133 
b_boat   -1.291 -0.420   -0.183  1.153   1.043   -0.194   0.243 -0.361   -0.981  -0.040 
b_train   3.159 -0.757    1.040  1.498  -0.194    4.153  -0.208  0.257    1.922   1.434 
c_plane  -0.954  1.698    1.347 -0.465   0.243   -0.208   1.791  0.909    0.259   0.394 
c_boat    0.488  1.668    1.813 -1.157  -0.361    0.257   0.909  2.290    1.572   0.269 
c_train   3.111  1.091    0.806 -0.775  -0.981    1.922   0.259  1.572    4.097   2.001 
d_plane   1.100  0.120   -0.324  0.133  -0.040    1.434   0.394  0.269    2.001   2.231 
…
最终需要的是一个数据框,其中每一类运输飞机、船只、火车各有一行,给定类别内每一种可能的协方差各有一列:

           aa       ab      ac     ad       ba     bb       bc     bd       ca     cb   …   <dd>
plane   4.419    0.018  -0.954  1.100    0.018  2.498   -0.465  0.133   -0.954  -0.465  …   
boat    2.636   -0.420   1.668  0.120   -0.420  1.043   -0.361  …               
train   …                                           
<…> 
然后,我尝试使用整形2中的dcast,但在如何使用该函数生成最终结果方面遇到了困难。有什么想法吗?如果有比我要走的更简单的方法,我很高兴听到

tidyverse方法可以是将行名作为列,将数据转换为长格式。从两个列名以及行名中获取字符串的第一部分,仅保留两个列名匹配的行并转换为宽格式

library(tidyverse)

df %>%
  rownames_to_column() %>%
  pivot_longer(cols =-rowname) %>%
  mutate(key = paste0(sub("_.*", "", rowname), sub("_.*", "", name)), 
         rowname = sub(".*_", "", rowname), name = sub(".*_", "", name)) %>%
  filter(rowname == name) %>%
  select(-rowname) %>%
  pivot_wider(names_from = key, values_from = value)

# A tibble: 3 x 17
#  name    aa     ab     ac    ad     ba    bb     bc     bd     ca     cb ....
#  <chr> <dbl>  <dbl>  <dbl> <dbl>  <dbl> <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#1 plane  4.42  0.018 -0.954   1.1  0.018  2.50 -0.465  0.133 -0.954 -0.465
#2 boat   2.64 -0.42   1.67   NA   -0.42   1.04 -0.361 NA      1.67  -0.361
#3 train  2.67  1.04   0.806  NA    1.04   4.15  1.92  NA      0.806  1.92 
tidyverse方法可以是将行名作为列,将数据转换为长格式。从两个列名以及行名中获取字符串的第一部分,仅保留两个列名匹配的行并转换为宽格式

library(tidyverse)

df %>%
  rownames_to_column() %>%
  pivot_longer(cols =-rowname) %>%
  mutate(key = paste0(sub("_.*", "", rowname), sub("_.*", "", name)), 
         rowname = sub(".*_", "", rowname), name = sub(".*_", "", name)) %>%
  filter(rowname == name) %>%
  select(-rowname) %>%
  pivot_wider(names_from = key, values_from = value)

# A tibble: 3 x 17
#  name    aa     ab     ac    ad     ba    bb     bc     bd     ca     cb ....
#  <chr> <dbl>  <dbl>  <dbl> <dbl>  <dbl> <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#1 plane  4.42  0.018 -0.954   1.1  0.018  2.50 -0.465  0.133 -0.954 -0.465
#2 boat   2.64 -0.42   1.67   NA   -0.42   1.04 -0.361 NA      1.67  -0.361
#3 train  2.67  1.04   0.806  NA    1.04   4.15  1.92  NA      0.806  1.92 

下面是使用base R的另一种方法:

提取每个单独车辆的协方差子矩阵; 将该子矩阵展开为向量; 将行向量合并回矩阵。 附加的代码是在将前缀组合粘贴在一起的基础上,为最终需求获取正确的列名

按字母顺序对行+列名称排序
cov_mat这里是另一种使用基础R的方法:

提取每个单独车辆的协方差子矩阵; 将该子矩阵展开为向量; 将行向量合并回矩阵。 附加的代码是在将前缀组合粘贴在一起的基础上,为最终需求获取正确的列名

按字母顺序对行+列名称排序
cov_mat几乎在那里-我得到一个错误:pivot_中的错误更长了,cols=-rowname:找不到函数pivot_更长了。我已经运行了tidyverse,并且刚刚运行了tidyr和tidyverse的update.packages。@JMQ您能运行install.packagestidy吗?如果您运行PackageVersionDirr,它应该返回[1]“1.0.0”。出现了一些问题,因此我必须删除并重新安装tidyr,但该函数现在正在工作。现在我只是想把你的代码映射到我的前男友,因为我在每个单元格中都会收到警告和列表。这是完整的数据。前缀是e\u/p\u/a\u/g\u/pres\u。后缀都是_1,没有必要。差不多到了-我得到一个错误:pivot_中的错误更长了,cols=-rowname:找不到pivot_函数更长了。我已经运行了tidyverse,并且刚刚运行了tidyr和tidyverse的update.packages。@JMQ您能运行install.packagestidy吗?如果您运行PackageVersionDirr,它应该返回[1]“1.0.0”。出现了一些问题,因此我必须删除并重新安装tidyr,但该函数现在正在工作。现在我只是想把你的代码映射到我的前男友,因为我在每个单元格中都会收到警告和列表。这是完整的数据。前缀是e\u/p\u/a\u/g\u/pres\u。后缀都是_1,没有必要。这适用于我提供的较短的玩具示例-真棒!但sapply正在将我的最终需求简化为一个矩阵,由58种车型中的每种车型的一个列表组成。调用final_need[[1]]为船提供了协方差向量,final_need[[2]]为飞机提供了协方差向量。我可以处理这个问题,但有没有想过强迫Sappy像它为你做的那样行事?这是完整的数据。前缀是e\u/p\u/a\u/g\u/pres\u。后缀都是_1,没有必要。我检查了您的完整数据,但这里不同前缀之间的协方差并不都存在,例如,焊工_1仅与前缀pres一起出现,而不与任何其他前缀一起出现。因此,sapply无法将数据简化为矩阵,而是返回长度不常见的向量列表。你可能需要重新考虑想要的输出。这适用于我提供的较短的玩具示例-太棒了!但sapply正在将我的最终需求简化为一个矩阵,由58种车型中的每种车型的一个列表组成。调用final_need[[1]]为船提供了协方差向量,final_need[[2]]为飞机提供了协方差向量。我可以处理这个问题,但有没有想过强迫Sappy像它为你做的那样行事?这是完整的数据。前缀是e\u/p\u/a\u/g\u/pres\u。后缀都是_1,没有必要。我检查了您的完整数据,但这里不同前缀之间的协方差并不都存在,例如,焊工_1仅与前缀pres一起出现,而不与任何其他前缀一起出现。因此,sapply无法将数据简化为矩阵,而是返回长度不常见的向量列表。您可能需要重新考虑所需的输出。。