Трофическое положение / высота в пищевых сетях (следующие пути в сетях) - PullRequest
6 голосов
/ 06 октября 2011

В рамках разработки демонстрации для пакета, над которым я работаю, мне нужно дать количественную оценку классической экологической пищевой сети, как описано ниже.Я проверил vegan, bipartite и 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 ]

3 голосов
/ 07 октября 2011

Это классическая теория графов. У вас есть ориентированный граф, где животные - это узлы, а «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(LG,Inf,mode="out")
[1] 6 5 2 3 1 1

, который должен быть в порядке A, B, C, D, E, F. Обратите внимание на использование Inf, чтобы прекратить ограничение окрестности, и использование mode = "out", чтобы следовать только краям графика в направлении приема пищи.

Все эти разговоры о пищевых цепях делают меня голодным. Надеюсь, что вы начали.

Barry

2 голосов
/ 07 октября 2011

Вот один из подходов к вычислению трофических высот, к которым вы стремитесь.

Скажем, матрица 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...