食物网中的营养位置/高度(遵循网络中的路径)

时间:2011-10-06 18:50:33

标签: r social-networking

作为开发我正在开发的软件包演示的一部分,我需要量化一个经典的生态食品网,如下所述。我已经检查了纯素,二分和sna,但没有看到任何能够满足我需要的东西,尽管我可能错了 - 那些都是大包装。因此,我想知道这个想法是否已经在包中,或者是否有人有一个聪明的方法来计算结果。好像它应该是一个包。

食物网可以通过物种A:F之间的相互作用矩阵来描述,如代码和图中所示。换句话说,人们会说“A吃B吃E”等(很难在矩阵中看到,在图中是微不足道的。)

species <- LETTERS[1:6]

links <- c(0, 1, 0, 0, 0, 0,
    1, 0, 1, 1, 1, 0,
    0, 1, 0, 0, 1, 0,
    0, 1, 0, 0, 1, 1,
    0, 1, 1, 1, 0, 0,
    0, 0, 0, 1, 0, 0)

L <- matrix(links, nrow = 6, byrow = TRUE,
    dimnames = list(species, species))

我想计算每个物种的营养位置和营养高度。营养位置定义为特定物种+ 1下食物链中物种的总数。在图中,A的营养位置为6,D为3,另一方面,营养高度为平均值。物种在其参与的每个独立链中的位置。物种B连接到4个不同的链(路径);它的高度是当时认为的位置的平均值:(3 + 3 + 3 + 2)/ 4 = 2.75。

计算上,需要读取矩阵L,然后通过矩阵隐含的不同路径来计算所需的值。

如果这不是太迟钝,有没有人知道会这样做的包,或者看到一种方法来跟踪路径并计算各种长度/选项?它“感觉”必须有一些应该有效的递归/应用方法,但我不想重新发明。

先谢谢

a simple food web

2 个答案:

答案 0 :(得分:3)

这是经典的图论理论。你所拥有的是有向图,其中动物是节点,'A吃B'是边缘。然后你的矩阵是一个编码边缘的邻接矩阵(但你可能想要一半的矩阵为0,所以你没有A吃B和B吃A.同样,除非你有吃人的行为,否则在对角线上为零)。这是另一个答案中链接的有向无环图。

图论的包列在图形模型任务视图中:

http://ftp.heanet.ie/mirrors/cran.r-project.org/web/views/gR.html

我认为igraph会做你想要的。首先从矩阵中创建一个图形对象(使用只有上三角形的修改矩阵):

> LG=graph.adjacency(L)
> LG
Vertices: 6 
Edges: 7 
Directed: TRUE 
Edges:

[0] 'A' -> 'B'
[1] 'B' -> 'C'
[2] 'B' -> 'D'
[3] 'B' -> 'E'
[4] 'C' -> 'E'
[5] 'D' -> 'E'
[6] 'D' -> 'F'

然后你可以使用neighborhood.size来获得营养位置:

> neighborhood.size(LG,Inf,mode="out")
[1] 6 5 2 3 1 1

应该按顺序A,B,C,D,E,F。注意使用Inf来停止限制邻域,并使用mode =“out”只跟随吃饭方向的图形边缘。

所有关于食物链的讨论让我感到饥饿。希望能让你开始。

百里

答案 1 :(得分:2)

这是计算你所追求的营养高度的一种方法。

假设矩阵L编码DAG,其中每行中的物种与每列中的物种相关联。 L_(i,j)=1表示spp_i吃spp_j。

然后L*L表示连接每对物种的两步“营养路径”的数量,L*L*L包含三步路径的数量,依此类推。在它们之间,“矩阵幂”集记录了连接节点对的所有路径,无论长度如何。

根据您的描述,物种的营养高度是一个加上连接到图表顶端的“叶子节点”之一的所有路径的平均路径长度。

## Here I've edited the matrix L to make it a DAG
species <- LETTERS[1:6]

links <-
  c(0, 1, 0, 0, 0, 0,
    0, 0, 1, 1, 1, 0,
    0, 0, 0, 0, 1, 0,
    0, 0, 0, 0, 1, 1,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0)

L <- matrix(links, nrow = 6, byrow = TRUE,
    dimnames = list(FROM=species, TO=species))

此函数(使用expm包中的运算符)应该可以满足您的需求。它可以做一些更详细的评论,但如果我有时间的话,我会稍后补充。

library(expm) ## provides "%^%", a matrix power operator

calcHeight <- function(MAT) {
    ## Find 'leaf nodes' (i.e. species that are only eaten,
    ## and don't eat any others)
    leaves <- which(rowSums(L)==0)

    ## Find the maximum possible chain length (if this is a DAG)
    maxHeight <- nrow(MAT) - length(leaves) - 1
    ## Then use it to determine which matrix powers we'll need to calculate.
    index <- seq_len(maxHeight)

    paths <- lapply(index, FUN=function(steps) MAT %^% steps)
    pathSteps <- lapply(index, FUN=function(steps) (1 + steps) * paths[[steps]])

    ## Trophic height is expressed relative to leaf nodes
    paths <- Reduce("+", paths)[-leaves, leaves]
    pathSteps <- Reduce("+", pathSteps)[-leaves, leaves]

    rowSums(pathSteps)/rowSums(paths)
}

calcHeight(L)
   A    B    C    D 
3.75 2.75 2.00 2.00