基于 R 中其他数据帧的子集数据帧为 Mantel 测试创建对称矩阵

Subset dataframe based on other dataframe in R to create symmectical matrices for Mantel Test

我是 R 的新手,需要建议如何根据另一个数据帧数据对数据帧进行子集化,以便它们匹配,查看行数和列数。
我的总体目标是在不同版本的测试套件之间执行 Mantel 测试。 为此,我必须比较版本 1 和版本 2 中存在的测试用例子集,因为在版本 2 中添加了更多测试用例,但对于 Mantel 测试,您需要(最好)两个对称矩阵。
我的矩阵看起来如何(小例子,它们最多可以有 400 万个字段):

File | testA | testB | testC | ...
testA|  0.0  | 0.62  |  0.45 | ...
testB|  0.62 | 0.0   |  0.12 | ...
testC|  0.45 | 0.12  |  0    | ...

目前我在做什么:

matrixA<- read.csv("data\distanceMatricesJacksonDatabindV112\dm_jaccard.csv", header = FALSE)
matrixB<- read.csv("data\distanceMatricesJacksonDatabindV112\dm_NCD.csv", header = FALSE)
testMantel = mantel(matrixA, matrixB, method = "spearman", permutations = 99, na.rm = TRUE)

此代码读取我的距离矩阵(csv 格式)作为数据帧,然后对它们执行 Mantel 测试。它目前不包括 headers 作为 headers,从那时起比较就不起作用了。但是,当我选择“TRUE”时,它们可用并用作 headers,如您在此屏幕截图中所见:

这仅适用于数据帧之间的行数和列数相同的情况。因此,我正在寻找一种方法来确保只有 MatrixA 中存在的条目(由第一列和第一行标识)将从 MatrixB 提取到 MatrixC,然后与 MatrixA 进行比较,以寻找世代变化。
所以这就是我需要它的样子:

Matrix A                 Matrix B                         Result: Matrix C
File | testA | testB |   File | testA | testB | testC |   File | testA | testB |
testA|  0.0  | 0.643 |   testA|  0.0  | 0.3   |  0.64 |   testA|  0.0  | 0.3   |
testB| 0.643 | 0.0   |   testB|  0.3  | 0.0   |  0.2  |   testB|  0.3  | 0.0   | 
                         testC|  0.64 | 0.2   |  0.0  |   

如示例所示,testB 必须在 Matrix A 和 Matrix B 之间发生变化,因为值从 0.643 变为 0.3。 TestC 不应出现在 Matrix C 中,因为 Matrix A 不知道它。同样重要的是:新测试不会自动添加到底部。它们可以位于矩阵中旧案例之间的任何位置。 我已经尝试过这个(以及更多)但我收到一条错误消息说“non-square matrix”

required_df <- jaccardV2[jaccardV2$V1 %in% jaccard$V1,]

如果有任何帮助,我将不胜感激

更新:我找到了解决方案并在上次添加了post

这是一种比较两个对称矩阵(距离或相关性)并提取在两者中找到的 rows/columns 的方法。首先我们需要一些可重现的数据:

set.seed(42)
x <- matrix(rnorm(36, 36, 6), 6, 6)
colnames(x) <- paste0("test", LETTERS[1:6])
MatA <- x[, sort(sample(1:6, 4))]
MatB <- x[, sort(sample(1:6, 4))]
(MatA.cor <- cor(MatA))
#            testA      testB     testE      testF
#  testA 1.0000000  0.1978459 0.5318998  0.1388820
#  testB 0.1978459  1.0000000 0.3979890 -0.1806799
#  testE 0.5318998  0.3979890 1.0000000  0.4346770
#  testF 0.1388820 -0.1806799 0.4346770  1.0000000
(MatB.cor <- cor(MatB))
#            testA      testC      testE     testF
#  testA 1.0000000  0.0552819  0.5318998 0.1388820
#  testC 0.0552819  1.0000000 -0.3562452 0.5533406
#  testE 0.5318998 -0.3562452  1.0000000 0.4346770
#  testF 0.1388820  0.5533406  0.4346770 1.0000000

由于我们使用一个矩阵来创建 MatA 和 MatB,因此相关性是相同的。在您的实际数据中,它们会有所不同。 MatA 包括测试 A、B、E 和 F,而 MatB 包括测试 A、C、E 和 F。我们要创建具有相同测试的矩阵:

both <- intersect(colnames(MatA.cor), colnames(MatB.cor))
both
#  [1] "testA" "testE" "testF"

测试 A、E 和 F 对两个矩阵都是通用的,因此我们提取了这些:

MatA.cor[both, both]
#            testA     testE    testF
#  testA 1.0000000 0.5318998 0.138882
#  testE 0.5318998 1.0000000 0.434677
#  testF 0.1388820 0.4346770 1.000000
MatB.cor[both, both]
#            testA     testE    testF
#  testA 1.0000000 0.5318998 0.138882
#  testE 0.5318998 1.0000000 0.434677
#  testF 0.1388820 0.4346770 1.000000

我找到了这个问题的答案,我将在下面的代码片段中列出。感谢@dcarlson 的帮助,它让我离最终解决方案更近了一步。 为了提取两个矩阵中都存在的子集,我想出了这个函数。

get_version_subset <- function(v1_matrix, v2_matrix){
rownames(v1_matrix) <- v1_matrix[,1]
v1_matrix <- v1_matrix[,-1]
rownames(v2_matrix) <- v2_matrix[,1]
v2_matrix <- v2_matrix[,-1]
subsetList <- intersect(colnames(v1_matrix), colnames(v2_matrix))
return(subsetList)
}

下一步我安装了库 tidyverse。我正在过滤“文件”,因为我的第一列有这个名称。

subsetList <- get_version_subset(matrix1, matrix2)
subset <- matrix2%>%filter(File %in% matrix1$File) %>% select(1, subsetList)

最后,您需要调整新矩阵“子集”以确保标签设置正确,我已在此函数中完成:

adjust_first_column <- function(matrix) {
rownames(matrix) <- matrix[,1]
adjustedMatrix <- matrix[,-1]
return(adjustedMatrix)
}

希望这对以后的其他人有所帮助!