【问题标题】:R: how to convert a data frame to an assymetric matrix with an empty cornerR:如何将数据帧转换为具有空角的非对称矩阵
【发布时间】:2022-12-14 10:07:57
【问题描述】:

我有以下数据框:

table <- data.frame(pop_1 = c("AL","AL","AL","AL","AL","AL","AL","ALT","ALT","ALT","ALT","ALT","ALT","BU","BU","BU","BU","BU","IRK","IRK","IRK","IRK","KK","KK","KK","KYA","KYA","TU"),
                    pop_2 = c("ALT","BU","IRK","KK","KYA","TU","ZAB","BU","IRK","KK","KYA","TU","ZAB","IRK","KK","KYA","TU","ZAB","KK","KYA","TU","ZAB","KYA","TU","ZAB","TU","ZAB","ZAB"),
                    value = c(0.43447,0.15267,0.25912,0.10435,0.19238,0.19186,0.18155,0.34969,0.07506,0.29206,0.13597,0.46354,0.17870,0.18658,0.02297,0.08851,0.18950,0.05176,0.12086,0.02690,0.29669,0.05551,0.04910,0.15779,0.03276,0.23422,0.00568,0.22181))

如何将其转换为具有空(或 NA 等)单元格的非对称矩阵,如下所示:

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    对您的数据框进行细微更改,在开头添加额外的“AL”、“AL”、“NA”组合。你会想在最后为一个额外的“ZAB”做同样的事情:

    df<- data.frame(pop_1 = c("AL","AL","AL","AL","AL","AL","AL","AL","ALT","ALT","ALT","ALT","ALT","ALT","BU","BU","BU","BU","BU","IRK","IRK","IRK","IRK","KK","KK","KK","KYA","KYA","TU"),
                  pop_2 = c("AL","ALT","BU","IRK","KK","KYA","TU","ZAB","BU","IRK","KK","KYA","TU","ZAB","IRK","KK","KYA","TU","ZAB","KK","KYA","TU","ZAB","KYA","TU","ZAB","TU","ZAB","ZAB"),
                  value = c(NA,0.43447,0.15267,0.25912,0.10435,0.19238,0.19186,0.18155,0.34969,0.07506,0.29206,0.13597,0.46354,0.17870,0.18658,0.02297,0.08851,0.18950,0.05176,0.12086,0.02690,0.29669,0.05551,0.04910,0.15779,0.03276,0.23422,0.00568,0.22181))
    
    library(tidyverse)
    pivot_wider(df, names_from=pop_1, values_from=value)
    
     pop_2     AL     ALT      BU     IRK      KK      KYA     TU
      <chr>  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>    <dbl>  <dbl>
    1 AL    NA     NA      NA      NA      NA      NA       NA    
    2 ALT    0.434 NA      NA      NA      NA      NA       NA    
    3 BU     0.153  0.350  NA      NA      NA      NA       NA    
    4 IRK    0.259  0.0751  0.187  NA      NA      NA       NA    
    5 KK     0.104  0.292   0.0230  0.121  NA      NA       NA    
    6 KYA    0.192  0.136   0.0885  0.0269  0.0491 NA       NA    
    7 TU     0.192  0.464   0.190   0.297   0.158   0.234   NA    
    8 ZAB    0.182  0.179   0.0518  0.0555  0.0328  0.00568  0.222
    

    编辑:

    df2<-df
    names(df2)<-c("pop_2", "pop_1", "value")
    rbind(df, df2) %>% pivot_wider(names_from=pop_1, values_from=value) %>% arrange(pop_2)
    

    【讨论】:

    • 这就对了!谢谢,我应该深入研究一下tidyverse。
    • pivot_wider() 是一个特别强大的功能——尤其是values_fn= 属性。 PS 这是一个额外的基础 R 方法 xtabs(value ~ pop_1 + pop_2, data=df, na.action=NULL)
    • 我仔细检查了pivot_wider() 解决方案,发现 ZAB 不见了。在首次提及之前,应添加带有 NA 的额外人口值,但这是另一回事了。
    • 是的,因为数据中没有那个,我们正在处理矩阵的三角形。我在数据的开头加了一行AL, AL, NA,最后需要ZAB, ZAB, NA。数据是这样的。这是一个想法,将数据与翻转数据绑定(有效地 df[c(2,1,3)]),这将使数据集更像矩阵(仍然没有对角线)。您可以稍后使用upper.tri()lower.tri() 删除矩阵的一部分。见编辑
    【解决方案2】:

    创建数据框 pop_1 和 pop_2 列中所有唯一值的向量。这将是矩阵的行和列的名称。

    populations <- unique(c(table$pop_1, table$pop_2))
    

    使用 matrix 函数创建一个空矩阵,其行数和列数与步骤 1 中的向量相同。使用 value 参数将矩阵的默认值设置为 NA。

    matrix <- matrix(NA, nrow = length(populations), ncol = length(populations))
    

    使用 rownames 和 colnames 函数将矩阵的行和列的名称设置为 populations 向量中的值。

    rownames(matrix) <- populations
    colnames(matrix) <- populations
    

    使用 for 循环遍历数据框的行。对于每一行,使用 pop_1 和 pop_2 列在矩阵中找到相应的单元格,并使用 value 列设置这些单元格的值。

    for (i in 1:nrow(table)) {
      row_name <- table[i, "pop_1"]
      col_name <- table[i, "pop_2"]
      value <- table[i, "value"]
      matrix[row_name, col_name] <- value
    }
    

    在这些步骤之后,矩阵应该是一个不对称矩阵,在适当的单元格中具有来自数据框的值,在所有其他单元格中具有 NA 。

    当您查看矩阵的结果时:

           AL     ALT      BU     IRK      KK     KYA      TU     ZAB
    AL  NA 0.43447 0.15267 0.25912 0.10435 0.19238 0.19186 0.18155
    ALT NA      NA 0.34969 0.07506 0.29206 0.13597 0.46354 0.17870
    BU  NA      NA      NA 0.18658 0.02297 0.08851 0.18950 0.05176
    IRK NA      NA      NA      NA 0.12086 0.02690 0.29669 0.05551
    KK  NA      NA      NA      NA      NA 0.04910 0.15779 0.03276
    KYA NA      NA      NA      NA      NA      NA 0.23422 0.00568
    TU  NA      NA      NA      NA      NA      NA      NA 0.22181
    ZAB NA      NA      NA      NA      NA      NA      NA      NA
    

    【讨论】:

    • 我希望有一个更简单的解决方案,但这个解决方案效果很好。
    • 使用库函数可能有更简单的方法,但我不知道
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多