【问题标题】:Subset dataframe based on other dataframe in R to create symmectical matrices for Mantel Test基于 R 中另一个数据帧的子集数据帧,为 Mantel 测试创建对称矩阵
【发布时间】:2021-07-06 18:38:07
【问题描述】:

我是 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 测试。它目前不包括标题作为标题,因为那时比较不起作用。但是,当我选择“TRUE”时,它们可用并用作标题,如您在此屏幕截图中所见:

这仅适用,只要数据帧之间的行数和列数相同。因此,我正在寻找一种方法来确保只有 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 必须在矩阵 A 和矩阵 B 之间发生变化,因为值从 0.643 变为 0.3。 TestC 不应出现在矩阵 C 中,因为矩阵 A 不知道它。同样重要的是:新测试不会自动添加到底部。它们可以位于矩阵中的任何位置,介于旧案例之间。 我已经尝试过这个(以及更多),但我收到一条错误消息,上面写着“非方阵”

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

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

更新:我已经找到了解决方案,并在上一篇文章中添加了它

【问题讨论】:

    标签: r dataframe matrix data-science subset


    【解决方案1】:

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

    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
    

    【讨论】:

    • 感谢您的帮助!我觉得这朝着正确的方向发展,但 R studio 告诉我“cor(jaccard) 中的错误:'x' 必须是数字”。我想知道我在导入时是否做错了什么?
    • 我应该使用 MatA.cor 和 MatB.cor 来创建和提取行/列。我已经进行了这些更正。您没有使用相关矩阵,因此您应该使用距离矩阵的名称:both
    • 好的,我已经根据你的建议更新了我的描述和实现,但有些东西仍然没有按应有的方式工作。我注意到了一些东西。当我在 csv 读数中选择“Headers = TRUE”时,它会告诉我有 73 个 obs。 74 个变量。当我打开标题时,相关性不起作用,因为它只是将 V1、V2、V3 等放在第一列,但它说 74 obs。 74 个变量。这可能很重要吗?非常感谢您的帮助!
    • 您应该使用“headers=TRUE”(注意大写,R 区分大小写)。您的第一列是测试 ID,因此您的距离矩阵似乎为 73x73。但您不断更改你的矩阵的名称。它是 MatrixA 还是 jaccard?第一列 File 和你的图片一样吗?看来你需要将第一列转换为行名才能有一个有效的距离矩阵,例如 rownames(MatrixA)
    • 尝试 readLines("data\\distanceMatricesJacksonDatabindV112\\dm_jaccard.csv", 5) 并发布生成的内容,以便我们查看文件的外观。它可能不是正确的 .csv 文件。
    【解决方案2】:

    我已经找到了这个问题的答案,我将在下面的代码 sn-p 中列出。感谢@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)
    }
    

    希望这将在未来对其他人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 2016-12-25
      • 2019-05-25
      • 2021-10-16
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      相关资源
      最近更新 更多