【问题标题】:Collapse species matrix to site by species matrix按物种矩阵将物种矩阵折叠到站点
【发布时间】:2017-06-30 00:58:40
【问题描述】:

提前道歉,我很难为这个问题命名。我有一个物种相互作用矩阵,其中的列和行代表物种,矩阵填充是它们相互作用的频率:

matrix<-   2A   2B   2C   
         1A 1   2    4      
         1B 0   1    1    
         1C 5   4    1    

我想制作一个如下形式的矩阵:

 mat<-        
            comm
     1A_2A   1
     1A_2B   2
     1A_2C   4
     1B_2A   0
     1B_2B   1
     1B_2C   1
     1C_2A   5
     1C_2B   4
     1C_2C   1

其中物种相互作用变为行,列可以是任何变量,但矩阵填充仍然是相互作用的频率,结构仍然是矩阵。这样,矩阵采用社区 x 物种矩阵的形式。我想以这种方式折叠矩阵并保留矩阵形式的原因是启用library(vegetarian) 中的函数,例如需要矩阵形式的d()

【问题讨论】:

  • 我的印象是如果我使用 reshape 包,结构将成为一个数据框。结构会保持矩阵吗?
  • 您将一列吸收到新的行标签中,删除该列并留下一个 9x1 数字的东西
  • 没有理由维护矩阵,而 data.frame 更合适。
  • @thc 这是你的意见,但是 OP 已经明确解释了为什么他想要一个矩阵作为结果

标签: r


【解决方案1】:

使用:

m2 <- matrix(t(m1))
dimnames(m2) <- list(paste(rep(rownames(m1), each = nrow(m1)),
                           colnames(m1), sep = '_'),
                     'comm')

给予:

> m2
      comm
1A_2A    1
1A_2B    2
1A_2C    4
1B_2A    0
1B_2B    1
1B_2C    1
1C_2A    5
1C_2B    4
1C_2C    1

这是做什么的:

  • 您可以将矩阵视为二维向量。要获取矢量,您可以简单地使用c(m1)。这将首先给出一个向量,其中包含第一列的值,然后是第二列的值,依此类推。要按行顺序获取值,您可以使用t(m1) 转置矩阵。
  • 通过将其包装在matrix 中,您将获得一个单列矩阵,这是未指定列数或行数时的默认行为。因此,matrix(t(m1))matrix(t(m1), ncol = 1) 相同。
  • 最后,您创建一个长度为 2 的列表,其中包含行名 (paste(rep(rownames(m1), each = nrow(m1)), colnames(m1), sep = '_') 和列名 ('comm),并将其分配给 dimnames。新的行名是通过重复 m1 的每个行名的次数来创建的m1 中的列数,并使用列名向量粘贴这些列(将被回收)。

如果你想要列顺序的值,你可以将上面的代码修改为:

m2 <- matrix(m1)
dimnames(m2) <- list(paste(rownames(m1),
                           rep(colnames(m1), each = ncol(m1)), sep = '_'),
                     'comm')

给出相同的结果,但顺序不同:

> m2
      comm
1A_2A    1
1B_2A    0
1C_2A    5
1A_2B    2
1B_2B    1
1C_2B    4
1A_2C    4
1B_2C    1
1C_2C    1

或者你也可以使用reshape2-package:

library(reshape2)
d1 <- melt(m1)
rownames(d1) <- paste(d1$Var1, d1$Var2, sep = '_')
d1 <- d1[, 3, drop = FALSE]

返回一个数据框:

> d1
      value
1A_2A     1
1B_2A     0
1C_2A     5
1A_2B     2
1B_2B     1
1C_2B     4
1A_2C     4
1B_2C     1
1C_2C     1

要得到一个矩阵,你可以把d1换成as.matrix:as.matrix(d1)


使用过的数据:

m1 <- matrix(c(1,2,4,0,1,1,5,4,1), ncol = 3, byrow = TRUE,
             dimnames = list(c('1A','1B','1C'),c('2A','2B','2C')))

【讨论】:

  • 感谢您提供有用的解决方案。我怀疑这个问题会激怒一些人,但对于像我这样的新手 R 用户,像你这样的解决方案可以帮助我更好地理解语言,而不是对于那些更明显的人来说。我特别感谢您的注释清楚地解释了您的方法。因此,感谢您将时间投入到对我有帮助而不是无益的批评的解决方案上。
  • 感谢您提供有用的解决方案。我怀疑这个问题会激怒一些人,但对于像我这样的新手 R 用户,像你这样的解决方案可以帮助我更好地理解语言,而不是对于那些更明显的人来说。我特别感谢您的注释清楚地解释了您的方法。因此,感谢您将时间投入到对我有帮助而不是无益的批评的解决方案上。
  • @Danielle 很高兴我能帮上忙。我同意尝试更好地理解语言是件好事。我还在定期学习有关 R 的新知识 :-) 通过回答像您这样的问题。
【解决方案2】:

使用 dplyr/tidyverse:

library(tidyverse)

df <-   read.table(textConnection("2A   2B   2C   
         1A 1   2    4      
         1B 0   1    1    
         1C 5   4    1"), check.names=F)

new_df <- df %>% rownames_to_column("Species_1") %>% gather(key="Species_2", value="Interactions", -Species_1)


Species_1 Species_2 Interactions
1        1A        2A            1
2        1B        2A            0
3        1C        2A            5
4        1A        2B            2
5        1B        2B            1
6        1C        2B            4
7        1A        2C            4
8        1B        2C            1
9        1C        2C            1

【讨论】:

    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多