2017-06-30 32 views
0

提前道歉,我很难提出这个问题。我有一个物种相互作用矩阵,其中列和行代表品种,与基体填充是它们之间的相互作用的频率:按物种基质将物种基质折叠到位点

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())中的函数。

+0

[从广角重塑data.frame到长格式]的可能的复制(https://stackoverflow.com/questions/2185252/reshaping-data-frame-from全格式到长格式) –

+0

我在印象之下如果我使用重塑包,结构将成为一个数据框。结构会保持矩阵吗? – Danielle

+0

您将一列吸收到新的行标签中,丢弃该列并留下一个9x1的数字thingie – Dinesh

回答

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)。这将给出一个向量,其中第一列的值为第一列,然后是第二列的值,依此类推。要按行顺序获取值,可以使用​​转置矩阵。
  • 通过将其包装在matrix中,您将得到一列矩阵,这是在未指定列数或行数时的默认行为。因此,matrix(t(m1))matrix(t(m1), ncol = 1)相同。
  • 最后,创建长度2 rownames(paste(rep(rownames(m1), each = nrow(m1)), colnames(m1), sep = '_')和COLUMNNAMES('comm的列表),并分配给dimnames。新的rownames由m1和粘贴重复m1多次每个rowname作为列的数目创建那些具有列名称的向量(将被回收)。

如果你想在列顺序的值,则可以调整上述代码:

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 

为了得到一个矩阵,你可以只是包装d1as.matrixas.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'))) 
+1

感谢您提供有用的解决方案。我怀疑这个问题会挑起一些人,但对于像我这样的新手R用户来说,像你这样的解决方案可以帮助我更好地理解语言,而不是对于这些事情更明显的人来说。我特别感谢你的解释清楚你的方法的注释。所以谢谢你把时间花在帮助我的解决方案上,而不是毫无帮助的批评。 – Danielle

+0

感谢您提供有用的解决方案。我怀疑这个问题会挑起一些人,但对于像我这样的新手R用户来说,像你这样的解决方案可以帮助我更好地理解语言,而不是对于这些事情更明显的人来说。我特别感谢你的解释清楚你的方法的注释。所以谢谢你把时间花在帮助我的解决方案上,而不是毫无帮助的批评。 – Danielle

+0

@Danielle很高兴我能帮到你。我同意它很好地尝试更好地理解语言。我还经常学习关于R的新东西:-)通过回答诸如你的问题等等。 – Jaap

-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