【问题标题】:Loop through the rows of two columns in a dataframe to obtain values from a matrix循环遍历数据框中两列的行以从矩阵中获取值
【发布时间】:2022-08-18 23:54:16
【问题描述】:

我在 R 中工作以清理一些数据以分析它。 我有一个如下所示的数据框(df):

Strain1 Strain2
p1      p2
p2      p3
p3      p4
p4      p5
p5      p1

和一个看起来像这样的矩阵(distmat):

       p1     p2     p3     p4     p5
p1     0      0.1    0.3     0.4    0.9
p2     0.1     0     0.5     0.1    0.6
p3     0.3    0.5     0      0.8    0.3
p4     0.4    0.1    0.8      0     0.2
p5     0.9    0.6    0.3     0.2     0

我想在我的数据框中添加一列,它将采用 Strain1 和 Strain2,在数据矩阵中找到值,提取值,然后将其放入新列和同一行中。我需要为超过 1000 个数据点执行此操作。

为了参考我将从这个例子中得到的数据框:

Strain1 Strain2 dist
p1      p2       0.1
p2      p3       0.5
p3      p4       0.8
p4      p5       0.2
p5      p1       0.9

    标签: r for-loop data-wrangling


    【解决方案1】:

    base R 中的一个选项

    df$dist <- mat1[as.matrix(df)]
    

    -输出

    > df
      Strain1 Strain2 dist
    1      p1      p2  0.1
    2      p2      p3  0.5
    3      p3      p4  0.8
    4      p4      p5  0.2
    5      p5      p1  0.9
    

    数据

    df <- structure(list(Strain1 = c("p1", "p2", "p3", "p4", "p5"), Strain2 = c("p2", 
    "p3", "p4", "p5", "p1")), class = "data.frame", row.names = c(NA, 
    -5L))
    
    mat1 <- structure(c(0, 0.1, 0.3, 0.4, 0.9, 0.1, 0, 0.5, 0.1, 0.6, 0.3, 
    0.5, 0, 0.8, 0.3, 0.4, 0.1, 0.8, 0, 0.2, 0.9, 0.6, 0.3, 0.2, 
    0), dim = c(5L, 5L), dimnames = list(c("p1", "p2", "p3", "p4", 
    "p5"), c("p1", "p2", "p3", "p4", "p5")))
    

    【讨论】:

      【解决方案2】:

      base R 中的可能解决方案:

      df$dist <- apply(df, 1, \(x) mat[x[1], x[2]])
      df
      
      #>   Strain1 Strain2 dist
      #> 1      p1      p2  0.1
      #> 2      p2      p3  0.5
      #> 3      p3      p4  0.8
      #> 4      p4      p5  0.2
      #> 5      p5      p1  0.9
      

      【讨论】:

        【解决方案3】:

        一个tidyverse dplyr 方法:

        df<-tribble(~Strain1, ~Strain2,
                        "p1",      "p2",
                        "p2",      "p3",
                        "p3",      "p4",
                        "p4",      "p5",
                        "p5",      "p1")
        
        distmat<-matrix(runif(25), nrow=5, ncol=5,
                        dimnames = list(c(paste0("p", 1:5)),
                                        c(paste0("p", 1:5))))
        
        df <- df %>% 
          rowwise() %>% 
          mutate(dist = distmat[Strain2, Strain1])
        

        【讨论】:

          【解决方案4】:

          在这里进行疯狂的猜测,但是由于您将其称为 distmat,也许看看corrr 包中的便利函数shave()stretch() 是否有用,将distmat 减少为一个三角形并将其变为长格式.

          corrr::shave(corrr::as_cordf(mat1)) %>% 
            corrr::stretch(na.rm = TRUE)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-17
            • 1970-01-01
            • 1970-01-01
            • 2017-11-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多