作为开发我正在开发的软件包演示的一部分,我需要量化一个经典的生态食品网,如下所述。我已经检查了纯素,二分和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,然后通过矩阵隐含的不同路径来计算所需的值。
如果这不是太迟钝,有没有人知道会这样做的包,或者看到一种方法来跟踪路径并计算各种长度/选项?它“感觉”必须有一些应该有效的递归/应用方法,但我不想重新发明。
先谢谢
答案 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