Running 'community_MN_test.R' [161s]
  Running 'community_collection_test.R' [171s]
  Running 'community_test.R' [1s]
  Running 'community_trophic_links_test.R' [151s]
  Running 'graph_tests.R' [0s]
  Running 'run.R' [192s]
  Running 'util_test.R' [0s]
Running the tests in 'tests/community_MN_test.R' failed.
Complete output:
  > # Functions requiring M and/or N
  > TestBodyMassBins <- function()
  + {
  +     AssertEqual(c(1,3,10), BodyMassBins(c6), check.attributes=FALSE)
  +     AssertEqual(c(1,1,3), BodyMassBins(c6, n.bins=3), check.attributes=FALSE)
  +     AssertEqual(c(2,2,2,1,2,1,1,5,2,2,1,1,2,3,2,3,3,2,2,1,4,3,2,3,1,2,1,2,3,
  +                     4,1,4,5,5,3,6,5,6,4,4,4,7,3,3,3,6,6,4,4,4,4,6,7,10,10,10), 
  +                   BodyMassBins(TL84), check.attributes=FALSE)
  + 
  +     # TODO Warnings
  +     # AssertRaises(BodyMassBins(c1))
  +     # AssertRaises(BodyMassBins(c2))
  + 
  +     AssertRaises(BodyMassBins(TL84, n.bins=1))
  +     AssertRaises(BodyMassBins(TL84, upper=min(NP(TL84,'M')), 
  +                               lower=max(NP(TL84,'M'))))
  +     AssertRaises(BodyMassBins(TL84, lower=mean(NP(TL84,'M')), 
  +                               upper=max(NP(TL84,'M'))))
  +     AssertRaises(BodyMassBins(TL84, lower=min(NP(TL84,'M')), 
  +                               upper=mean(NP(TL84,'M'))))
  + }
  > 
  > TestResourceLargerThanConsumer <- function()
  + {
  +     AssertEqual(NULL, ResourceLargerThanConsumer(c1))
  +     AssertEqual(NULL, ResourceLargerThanConsumer(c2))
  +     AssertEqual(0, nrow(ResourceLargerThanConsumer(c6)))
  +     check <- ResourceLargerThanConsumer(TL84)
  +     AssertEqual(c('Cyclops varians rubellus', 'Leptodiaptomus siciloides'), 
  +                   check$resource)
  +     AssertEqual(c('Tropocyclops prasinus', 'Tropocyclops prasinus'), 
  +                   check$consumer)
  + }
  > 
  > TestSumNByClass <- function()
  + {
  +     AssertRaises(SumNByClass(c1))
  +     AssertRaises(SumNByClass(c2))
  +     AssertEqual(unname(NP(c6,'N')), 
  +                 unname(SumNByClass(c6, class=c('a','b','c'))))
  +     AssertEqual(sum(NP(c6,'N')), unname(SumNByClass(c6, class=c('a','a','a'))))
  +     AssertEqual(sum(NP(c6,'N')[1:2]), 
  +                 unname(SumNByClass(c6, class=c('a','a',NA))))
  +     AssertEqual(unname(c(NP(c6,'N')[3], sum(NP(c6,'N')[1:2]))), 
  +                 unname(SumNByClass(c6, class=c('a','a',''))))
  + 
  +     AssertEqual(c(invertebrate=1.8678e+06, producer=3.2107e+09, 
  +                   vert.ecto=2.2350e+00), SumNByClass(TL84))
  + 
  +     AssertEqual(as.numeric(c(NA,NA,NA)), 
  +                 unname(SumNByClass(BroadstoneStream)))
  +     AssertEqual(c('<unnamed>'=0, invertebrate=32081.3, producer=0.0), 
  +                 SumNByClass(BroadstoneStream, na.rm=TRUE))
  + 
  +     AssertRaises(SumNByClass(c6, class=NULL))
  + }
  > 
  > TestSumBiomassByClass <- function()
  + {
  +     AssertRaises(SumNByClass(c1))
  +     AssertRaises(SumNByClass(c2))
  +     AssertEqual(unname(Biomass(c6)), 
  +                 unname(SumBiomassByClass(c6, class=c('a','b','c'))))
  +     AssertEqual(sum(Biomass(c6)), 
  +                 unname(SumBiomassByClass(c6, class=c('a','a','a'))))
  +     AssertEqual(sum(Biomass(c6)[1:2]), 
  +                 unname(SumBiomassByClass(c6, class=c('a','a',NA))))
  +     AssertEqual(unname(c(Biomass(c6)[3], sum(Biomass(c6)[1:2]))), 
  +                 unname(SumBiomassByClass(c6, class=c('a','a',''))))
  + 
  +     AssertEqual(as.numeric(c(NA,NA,NA)), 
  +                 unname(SumBiomassByClass(BroadstoneStream)))
  +     AssertEqual(c('<unnamed>'=0, invertebrate=830.4337, producer=0), 
  +                 round(SumBiomassByClass(BroadstoneStream, na.rm=TRUE),4))
  + 
  +     AssertRaises(SumBiomassByClass(c6, class=NULL))
  + }
  > 
  > TestNvMLinearRegressions <- function()
  + {
  +     res <- NvMLinearRegressions(c1)
  +     AssertEqual('all', names(res))
  +     AssertEqual(NULL, res[[1]])
  +     res <- NvMLinearRegressions(c2)
  +     AssertEqual('all', names(res))
  +     AssertEqual(NULL, res[[1]])
  + 
  +     # Using default class of category - all NA as c6 does not have category
  +     res <- NvMLinearRegressions(c6)
  +     AssertEqual('all', names(res))
  +     AssertEqual(c(2.58,-1.04), unname(round(coef(res[['all']]), 2)))
  + 
  +     # class, NULL should result in a single lm object being returned
  +     res <- NvMLinearRegressions(c6, class=NULL)
  +     AssertEqual('all', names(res))
  +     AssertEqual(c(2.58,-1.04), unname(round(coef(res[['all']]), 2)))
  + 
  +     # Each node is in it's own class. Can't fit lm through one data point 
  +     # so should have 'all' and three NULLs
  +     res <- NvMLinearRegressions(c6, class=c('a','b','c'))
  +     AssertEqual(c('all','a','b','c'), names(res))
  +     AssertEqual(c(2.58,-1.04), unname(round(coef(res[['all']]), 2)))
  +     AssertEqual(list(a=NULL, b=NULL, c=NULL), res[2:4])
  + 
  +     # Node 1 in a different class to nodes 2 and 3
  +     res <- NvMLinearRegressions(c6, class=c('a','b','b'))
  +     AssertEqual(c('all', 'a', 'b'), names(res))
  +     AssertEqual(c(2.58,-1.04), unname(round(coef(res[['all']]), 2)))
  +     AssertEqual(c(1.14,-0.20), unname(round(coef(res[['b']]), 2)))
  +     AssertEqual(NULL, res[['a']])
  + 
  +     # category is default class
  +     res <- NvMLinearRegressions(TL84)
  +     AssertEqual(c('all', 'producer', 'invertebrate', 'vert.ecto'), names(res))
  +     AssertEqual(c(-2.69, -0.83), unname(round(coef(res[['all']]), 2)))
  +     AssertEqual(c(2.56, -0.41), unname(round(coef(res[['producer']]), 2)))
  +     AssertEqual(c(1.47, -0.32), unname(round(coef(res[['invertebrate']]), 2)))
  +     AssertEqual(c(-34.66, -11.63), unname(round(coef(res[['vert.ecto']]), 2)))
  + 
  +     # Some nodes lack both a category and N and M
  +     res <- NvMLinearRegressions(BroadstoneStream)
  +     AssertEqual(c(1.08, -0.74), unname(round(coef(res[['all']]), 2)))
  +     AssertEqual(c(1.08, -0.74), unname(round(coef(res[['invertebrate']]), 2)))
  +     AssertEqual(NULL, res[['<unnamed>']])
  +     AssertEqual(NULL, res[['producer']])
  + }
  > 
  > TestNvMTriTrophic1 <- function()
  + {
  +     # Recreates Table 1 from Cohen et al 2010 PNAS
  +     data(TL84, TL86, YthanEstuary)
  +     collection <- CommunityCollection(list(TL84, TL86, YthanEstuary))
  +     table <- NvMTriTrophicTable(collection)
  + 
  +     # Exclude the rows that include all nodes and links
  +     table <- head(table, -4)
  + 
  +     # Check to 2 dp
  +     table <- round(table, 2)
  + 
  +     # The data from the paper
  +     check <- matrix(c(
  +                6.33,    5.90,    7.29, 
  +                5.41,    3.43,    5.06, 
  +                5.99,    5.69,    6.15, 
  +               12.67,   11.79,   14.57, 
  +               11.02,    8.65,   10.51, 
  +               11.40,    9.12,   11.20, 
  +                1.15,    1.36,    1.39, 
  +                1.03,    1.05,    1.07, 
  +                4.84,    4.84,    4.43, 
  +               30.62,   28.56,   32.31, 
  +               20.78,   22.66,   21.98, 
  +                1.47,    1.26,    1.47, 
  +               19.96,   23.33,   16.88, 
  +               18.71,   20.63,   13.18,  # TL86 mean chain span 20.63 vs 20.62
  +                0.90,    0.91,    0.60, 
  +                1.07,    1.13,    1.28, 
  +                0.96,    1.03,    0.77, 
  +              264.00,  236.00,  379.00, 
  +             2500.00, 2601.00, 8281.00, 
  +                0.11,    0.09,    0.05, 
  +                5.28,    4.63,    4.16), ncol=3, byrow=TRUE)
  +     dimnames(check) <- dimnames(table)
  +     AssertEqual(table, check)
  + }
  > 
  > TestNvMTriTrophic2 <- function()
  + {
  +     # Recreates Table S3 from Cohen et al 2010 PNAS
  +     communities <- list(TL84, TL86, RemoveNodes(YthanEstuary,'POM (detritus)'))
  +     communities <- lapply(communities, RemoveIsolatedNodes)
  +     communities <- lapply(communities, RemoveCannibalisticLinks)
  + 
  +     res <- lapply(communities, function(community)
  +     {
  +         chains <- ThreeNodeChains(community, node.properties='M')
  +         MR <- chains$bottom.M
  +         MI <- chains$intermediate.M
  +         MC <- chains$top.M
  + 
  +         lp <- TLPS(community, node.properties='M')
  + 
  +         return (c('MR<=MI<=MC'=sum(MR<=MI & MI<=MC), 
  +                   'MR<=MC<MI'=sum(MR<=MC & MC<MI), 
  +                   'MI<MR<=MC'=sum(MI<MR  & MR<=MC), 
  +                   'MI<=MC<MR'=sum(MI<=MC & MC<MR), 
  +                   'MC<MR<MI'=sum(MC<MR  & MR<MI), 
  +                   'MC<MI<MR'=sum(MC<MI  & MI<MR), 
  +                   'All 2-chains'=nrow(chains),
  +                   'MR<MC'=sum(lp$resource.M<lp$consumer.M), 
  +                   'MR=MC'=sum(lp$resource.M==lp$consumer.M), 
  +                   'MR>MC'=sum(lp$resource.M>lp$consumer.M), 
  +                   'All links'=nrow(lp)))
  +     })
  +     res <- do.call('cbind', res)
  + 
  +     colnames(res) <- c('TL84', 'TL86', 'Ythan Estuary')
  + 
  +     # The data from the paper
  +     check <- matrix(c(  1001,  577,  1232,
  +                           30,   59,    65,
  +                           12,   10,    68,
  +                            0,    1,     3,
  +                            1,    3,     0,
  +                            0,    1,     3,
  +                         1044,  651,  1371,
  +                          262,  232,   368,
  +                            0,    0,     2,
  +                            2,    4,     9,
  +                          264,  236,   379), ncol=3, byrow=TRUE)
  + 
  +     colnames(check) <- colnames(res)
  +     rownames(check) <- rownames(res)
  +     AssertEqual(check, res)
  + }
  > 
  > TestNvMTriTrophic3 <- function()
  + {
  +     # Some of Doris' Icelandic streams communities have only producers and 
  +     # herbivores, which caused an earlier version of 
  +     # .NvMTrophicChainProperties() to fail with a nasty error.
  +     # Let's check some cases for simple communities
  +     AssertRaises(NvMTriTrophicStatistics(c1))
  +     AssertRaises(NvMTriTrophicStatistics(c2))
  +     AssertRaises(NvMTriTrophicStatistics(c3))
  +     AssertRaises(NvMTriTrophicStatistics(c4))
  +     AssertRaises(NvMTriTrophicStatistics(c5))
  + 
  +     # Resource-consumer
  +     rc <- Community(nodes=data.frame(node=c('R', 'C'),
  +                                      M=c(1, 10), 
  +                                      N=c(100, 1)), 
  +                     trophic.links=data.frame(resource='R', consumer='C'), 
  +                     properties=list(title='Resource-consumer', M.units='g', 
  +                                     N.units='m^-2'))
  +     tts <- NvMTriTrophicStatistics(rc)
  +     check <- data.frame(resource='R',
  +                         consumer='C',
  +                         length=3,
  +                         angle=-63.43494882292200998108,
  +                         slope=-2, 
  +                         stringsAsFactors=FALSE, 
  +                         row.names="1")
  +     AssertEqual(check, tts$links)
  + 
  +     AssertEqual(NULL, tts$three.node.chains)
  + 
  +     check <- data.frame(Node.1='R',
  +                         Node.2='C', 
  +                         chain.span=3,
  +                         count.chain.length=1,
  +                         sum.chain.length=3,
  +                         stringsAsFactors=FALSE)
  +     AssertEqual(check, tts$trophic.chains)
  + 
  +     # Tri-trophic chain
  +     tts <- NvMTriTrophicStatistics(c6)
  +     check <- data.frame(resource=c('R','C'),
  +                         consumer=c('C','P'),
  +                         length=c(2.52287874528033739807,1.56066730616973736723),
  +                         angle=c(-75.34856290594565564334,-11.28584933963889191944),
  +                         slope=c(-3.82497857878639635487, -0.19956289353132869446),
  +                         stringsAsFactors=FALSE, 
  +                         row.names=c("1","2"))
  +     AssertEqual(check, tts$links)
  + 
  +     check <- data.frame(bottom='R', 
  +                         intermediate='C', 
  +                         top='P',
  +                         Llower=2.52287874528033739807,
  +                         Lupper=1.56066730616973736723, 
  +                         two.span=4.08354605145007454325,
  +                         Alower=-75.34856290594565564334,
  +                         Aupper=-11.28584933963889191944,
  +                         Abetween=64.06271356630675484212,
  +                         stringsAsFactors=FALSE)
  +     AssertEqual(check, tts$three.node.chains)
  + 
  +     check <- data.frame(Node.1='R',
  +                         Node.2='C', 
  +                         Node.3='P', 
  +                         chain.span=4.08354605145007454325,
  +                         count.chain.length=2.00000000000000000000,
  +                         sum.chain.length=4.08354605145007454325,
  +                         stringsAsFactors=FALSE)
  +     AssertEqual(check, tts$trophic.chains)
  + }
  > 
  > TestNodesWithoutMOrN <- function()
  + {
  +     NodesWithoutMOrN <- cheddar:::.NodesWithoutMOrN
  +     AssertEqual('S', NodesWithoutMOrN(c1))
  +     AssertEqual('S', NodesWithoutMOrN(c2))
  +     AssertEqual(c('R','C'), NodesWithoutMOrN(c3))
  +     AssertEqual(c('R','C','P'), NodesWithoutMOrN(c4))
  +     AssertEqual(c('R','C','O'), NodesWithoutMOrN(c5))
  +     AssertEqual(0, length(NodesWithoutMOrN(c6)))
  +     AssertEqual(0, length(NodesWithoutMOrN(TL84)))
  +     AssertEqual('POM (detritus)', NodesWithoutMOrN(YthanEstuary))
  + }
  > 
  > TestNvMSlopeAndIntercept <- function()
  + {
  +     AssertEqual(NULL, NvMSlope(c1))
  +     AssertEqual(NULL, NvMSlope(c2))
  +     AssertEqual(NULL, NvMSlope(c3))
  +     AssertEqual(NULL, NvMSlope(c4))
  +     AssertEqual(NULL, NvMSlope(c5))
  +     AssertEqual(-1.04009302605305009592, NvMSlope(c6))
  +     AssertEqual(-0.82711453844476423569, NvMSlope(TL84))
  + 
  +     AssertEqual(NULL, NvMIntercept(c1))
  +     AssertEqual(NULL, NvMIntercept(c2))
  +     AssertEqual(NULL, NvMIntercept(c3))
  +     AssertEqual(NULL, NvMIntercept(c4))
  +     AssertEqual(NULL, NvMIntercept(c5))
  +     AssertEqual(2.57689795300774049380, NvMIntercept(c6))
  +     AssertEqual(-2.68627529180856106095, NvMIntercept(TL84))
  + 
  +     AssertEqual(NULL, NvMSlopeAndIntercept(c1))
  +     AssertEqual(NULL, NvMSlopeAndIntercept(c2))
  +     AssertEqual(NULL, NvMSlopeAndIntercept(c3))
  +     AssertEqual(NULL, NvMSlopeAndIntercept(c4))
  +     AssertEqual(NULL, NvMSlopeAndIntercept(c5))
  +     AssertEqual(c(slope=-1.04009302605305009592, 
  +                   intercept=2.57689795300774049380), 
  +                 NvMSlopeAndIntercept(c6))
  +     AssertEqual(c(slope=-0.82711453844476423569, 
  +                   intercept=-2.68627529180856106095), 
  +                 NvMSlopeAndIntercept(TL84))
  + }
  > 
  > TestNvMSlopeAndInterceptByClass <- function()
  + {
  +     AssertEqual(c(slope.all=-1.04009302605305009592), NvMSlopeByClass(c6))
  +     AssertEqual(c(slope.all=-0.82711453844476423569, 
  +                   slope.producer=-0.40715089579609509141, 
  +                   slope.invertebrate=-0.32431675051076519489, 
  +                   slope.vert.ecto=-11.62787086769622924010), 
  +                 NvMSlopeByClass(TL84))
  + 
  +     AssertEqual(c(intercept.all=2.57689795300774049380),NvMInterceptByClass(c6))
  +     AssertEqual(c(intercept.all=-2.68627529180856106095, 
  +                   intercept.producer=2.55833642234355362888, 
  +                   intercept.invertebrate=1.46560619016986248830, 
  +                   intercept.vert.ecto=-34.66097278952445748246), 
  +                 NvMInterceptByClass(TL84))
  + 
  +     AssertEqual(c(slope.all=-1.04009302605305009592, 
  +                   intercept.all=2.57689795300774049380), 
  +                 NvMSlopeAndInterceptByClass(c6))
  +     AssertEqual(c(slope.all=-0.82711453844476423569, 
  +                   slope.producer=-0.40715089579609509141, 
  +                   slope.invertebrate=-0.32431675051076519489, 
  +                   slope.vert.ecto=-11.62787086769622924010, 
  +                   intercept.all=-2.68627529180856106095, 
  +                   intercept.producer=2.55833642234355362888, 
  +                   intercept.invertebrate=1.46560619016986248830, 
  +                   intercept.vert.ecto=-34.66097278952445748246), 
  +                 NvMSlopeAndInterceptByClass(TL84))
  + 
  +     AssertEqual(c(slope.all=-0.73916494129624910059, 
  +                   slope.invertebrate=-0.73916494129624910059, 
  +                   'slope.<unnamed>'=NA,
  +                   slope.producer=NA,
  +                   intercept.all=1.07951558005480174884, 
  +                   intercept.invertebrate=1.07951558005480174884,
  +                   'intercept.<unnamed>'=NA,
  +                   intercept.producer=NA), 
  +                 NvMSlopeAndInterceptByClass(BroadstoneStream))
  + 
  +     AssertEqual(c(slope.all=-1.13010867280292459647,
  +                   slope.vert.endo=-2.46246611880339116851, 
  +                   'slope.<unnamed>'=-1.87594996135075309240, 
  +                   slope.vert.ecto=2.32192809488736218171,
  +                   intercept.all=1.43776079409099510897, 
  +                   intercept.vert.endo=2.95188840529695939452, 
  +                   'intercept.<unnamed>'=1.16171181260177314165, 
  +                   intercept.vert.ecto=0.00000000000000005773), 
  +                 NvMSlopeAndInterceptByClass(c8))
  + }
  > 
  > TestNvMConvexHull <- function()
  + {
  +     AssertEqual(0.5, cheddar:::.PolygonArea(c(0, 1, 0.5, 0), c(0, 0, 1, 0)))
  +     AssertEqual(1, cheddar:::.PolygonArea(c(0, 1, 1, 0, 0), c(0, 0, 1, 1, 0)))
  +     res <- NvMConvexHull(TL84)
  +     # Can't guarantee in ordering of points on the hull
  +     nodes <- c('Chaoborus punctipennis','Chromulina sp.',
  +                'Chrysosphaerella longispina','Keratella testudo','Phoxinus eos',
  +                'Phoxinus neogaeus','Umbra limi','Unclassified flagellates')
  +     AssertEqual(nodes, sort(res$nodes))
  +     AssertEqual(30.68266, round(res$area, 5))
  +     AssertEqual(matrix(c( -6.522879,  4.0791812,
  +                          -13.518557,  8.1731863,
  +                           -9.080399,  6.6020600,
  +                          -11.000000,  3.7781513,
  +                           -2.995679,  0.2944662,
  +                           -2.931814, -0.8761484,
  +                           -2.889410, -0.8794261,
  +                          -12.460924,  9.2741578), byrow=TRUE, ncol=2), 
  +                 unname(round(res$points[nodes,], 7)), 
  +                 tolerance=1e-7)
  + }
  > 
  > proc.time()
     user  system elapsed 
     0.26    0.01    0.26 
Running the tests in 'tests/community_collection_test.R' failed.
Complete output:
  > # Community collections
  > TestCommunityCollectionSingle <- function()
  + {
  +     # Test collections containing a single community
  +     for(community in list(c1,c2,c3,c4,c5,c6,TL84,TL86,SkipwithPond))
  +     {
  +         print(community)
  +         collection <- CommunityCollection(list(community))
  +         AssertEqual(1, length(collection))
  +         AssertEqual(CP(community,'title'), names(collection))
  +         AssertEqual(data.frame(summary(community), 
  +                                row.names=CPS(community)$title), 
  +                     summary(collection))
  + 
  +         AssertEqual(collection, CommunityCollection(collection))
  + 
  +         cpa <- CollectionCPS(collection)
  +         cpb <- data.frame(CPS(community), stringsAsFactors=FALSE)
  +         rownames(cpb) <- cpb$title
  +         AssertEqual(cpa, cpb)
  + 
  +         npa <- CollectionNPS(collection)
  +         npb <- cbind(community=CP(community,'title'), NPS(community))
  +         rownames(npb) <- NULL
  +         AssertEqual(npa, npb)
  +     
  +         if('c1'==CP(community, 'title'))
  +         {
  +             AssertEqual(NULL, CollectionTLPS(collection))
  +         }
  +         else
  +         {
  +             cpa <- CollectionTLPS(collection)
  +             cpb <- cbind(community=CP(community,'title'), TLPS(community))
  +             AssertEqual(cpa, cpb)
  +         }
  +     }
  + }
  > 
  > TestCommunityCollectionProperties <- function()
  + {
  +     # TODO Test these cases
  +     col <- CommunityCollection(list(TL84, TL86, YthanEstuary))
  + 
  +     # Functions that return a single value
  +     CollectionCPS(col)
  +     CollectionCPS(col, 'title')
  +     CollectionCPS(col, c(S='NumberOfNodes'))
  +     CollectionCPS(col, c(S='NumberOfNodes', L='NumberOfTrophicLinks'))
  + 
  +     # A function that return more than one value
  +     CollectionCPS(col, 'SumBiomassByClass')
  +     CollectionCPS(col, c(B='SumBiomassByClass'))
  +     CollectionCPS(col, list(list('SumBiomassByClass', class='kingdom')))
  +     CollectionCPS(col, list(B=list('SumBiomassByClass', class='kingdom')))
  +     CollectionCPS(col, list(S='NumberOfNodes', B=list('SumBiomassByClass', class='kingdom'), L='NumberOfTrophicLinks'))
  + 
  +     # Functions that return more than one value
  +     CollectionCPS(col, c('SumBiomassByClass', 'SumNByClass'))
  +     CollectionCPS(col, c(B='SumBiomassByClass', 'SumNByClass'))
  +     CollectionCPS(col, list(list('SumBiomassByClass', class='kingdom'), 'SumNByClass'))
  +     CollectionCPS(col, list(B=list('SumBiomassByClass', class='kingdom'), N='SumNByClass'))
  +     CollectionCPS(col, list(B=list('SumBiomassByClass', class='kingdom'), S='NumberOfNodes', N='SumNByClass'))
  +     CollectionCPS(col, list(B=list('SumBiomassByClass', class='kingdom'), N=list('SumNByClass', class='kingdom')))
  +     CollectionCPS(col, list(B=list('SumBiomassByClass', class='kingdom'), S='NumberOfNodes', N=list('SumNByClass', class='kingdom')))
  + 
  +     head(CollectionNPS(col))
  +     head(CollectionNPS(col, 'Biomass'))
  +     head(CollectionNPS(col, c(B='Biomass')))
  +     head(CollectionNPS(col, c(B='Biomass', 'M')))
  +     head(CollectionNPS(col, 'Log10MNBiomass'))
  + 
  +     head(CollectionTLPS(col))
  +     head(CollectionTLPS(col, node.properties='Biomass'))
  +     head(CollectionTLPS(col, node.properties=c(B='Biomass')))
  +     head(CollectionTLPS(col, node.properties=c(B='Biomass', 'M')))
  + 
  +     S2 <- Community(properties=list(title='Skipwith (no links)'), 
  +                                     nodes=NPS(SkipwithPond))
  +     col <- CommunityCollection(list(SkipwithPond, S2))
  +     head(CollectionTLPS(col))
  +     head(CollectionTLPS(col, link.properties='link.evidence'))
  +     NULL
  + }
  > 
  > TestCommunityCollectionFailures <- function()
  + {
  +     # Not communities
  +     AssertRaises(CommunityCollection(list()))
  +     AssertRaises(CommunityCollection(1))
  +     AssertRaises(CommunityCollection(''))
  +     AssertRaises(CommunityCollection(list(c1,'')))
  +     AssertRaises(CommunityCollection(list(c1,1)))
  + 
  +     # Duplications
  +     AssertRaises(CommunityCollection(list(c1,c1)))
  +     AssertRaises(CommunityCollection(list(c1,c2,c1)))
  + 
  +     # Inconsistent units
  +     AssertRaises(CommunityCollection(list(c5, c6)))
  + 
  +     # Modifications are illegal
  +     collection <- CommunityCollection(list(TL84))
  +     AssertRaises(collection[1] <- 1)
  +     AssertRaises(collection[[1]] <- 1)
  +     AssertRaises(collection$silly <- 1)
  +     AssertRaises(names(collection) <- letters[1:3])
  +     AssertRaises(length(collection) <- 1)
  + }
  > 
  > TestAggregateCommunitiesSingle <- function()
  + {
  +     # Aggregating a collection containing one community should not change 
  +     # anything
  +     for(community in list(c1,c2,c3,c4,c5,c6,TL84,TL86,SkipwithPond))
  +     {
  +         print(community)
  +         a <- community
  +         b <- AggregateCommunities(CommunityCollection(list(community)), 
  +                                   title=CP(community,'title'))
  + 
  +         # Node, trophic link and whole-community properties should not be 
  +         # different.
  +         npa <- NPS(a)
  +         npa <- npa[order(npa$node),]
  +         npb <- NPS(b)
  +         npb <- npb[order(npb$node),]
  +         AssertEqual(npa, npb)
  + 
  +         cpsa <- CPS(a)
  +         cpsa <- cpsa[order(names(cpsa))]
  +         cpsb <- CPS(b)
  +         cpsb <- cpsb[order(names(cpsb))]
  +         AssertEqual(cpsa, cpsb)
  + 
  +         if('c1'==CP(a, 'title'))
  +         {
  +             AssertEqual(0, NumberOfTrophicLinks(a))
  +             AssertEqual(0, NumberOfTrophicLinks(b))
  +             AssertEqual(NULL, TLPS(a))
  +             AssertEqual(NULL, TLPS(b))
  +         }
  +         else
  +         {
  +             tlpa <- TLPS(a)
  +             tlpa <- tlpa[order(tlpa$resource, tlpa$consumer),]
  +             rownames(tlpa) <- NULL
  +             tlpb <- TLPS(b)
  +             tlpb <- tlpb[order(tlpb$resource, tlpb$consumer),]
  +             rownames(tlpb) <- NULL
  +             AssertEqual(tlpa, tlpb)
  +         }
  +     }
  + }
  > 
  > TestAggregateCommunitiesFailures <- function()
  + {
  +     # Some failure cases
  +     collection <- CommunityCollection(list(c1,c2,c3,c4,c5))
  +     AssertRaises(AggregateCommunities(collection, 0))
  +     AssertRaises(AggregateCommunities(collection, 6))
  +     AssertRaises(AggregateCommunities(collection, 0:1))
  +     AssertRaises(AggregateCommunities(collection, 1:6))
  +     AssertRaises(AggregateCommunities(collection, ''))
  +     AssertRaises(AggregateCommunities(collection, c('c1','x')))
  + }
  > 
  > TestAggregateCommunitiesProperties <- function()
  + {
  +     # Aggregation of three very simple communities with no node or link
  +     # properties and only the 'title' community property
  +     collection <- CommunityCollection(list(c1,c2,c3))
  +     a <- AggregateCommunities(collection)
  +     AssertEqual(data.frame(node=c('S','R','C'), row.names=c('S','R','C')),NPS(a))
  +     AssertEqual(data.frame(resource=c('S','R'), consumer=c('S','C')), TLPS(a))
  +     AssertEqual('Aggregation of c1,c2,c3', CPS(a)$title)
  + 
  +     # Aggregation of two simple communities with a single node, a single link 
  +     # and a single community property
  +     x <- Community(nodes=data.frame(node='n', np='np'),
  +                    trophic.links=data.frame(resource='n', consumer='n', tlp='tlp'),
  +                    properties=list(title='x', cp='cp'))
  +     y <- Community(nodes=data.frame(node='n', np='np'),
  +                    trophic.links=data.frame(resource='n', consumer='n', tlp='tlp'),
  +                    properties=list(title='y', cp='cp'))
  +     collection <- CommunityCollection(list(x,y))
  +     a <- AggregateCommunities(collection)
  +     AssertEqual(data.frame(node='n', np='np', row.names='n'), NPS(a))
  +     AssertEqual(data.frame(resource='n', consumer='n', tlp='tlp'), TLPS(a))
  +     AssertEqual('Aggregation of x,y',  CPS(a)$title)
  +     AssertEqual('cp', CPS(a)$cp)
  +     
  +     # Aggregation of two simple communities with two node, two link 
  +     # and two community properties
  +     x <- Community(nodes=data.frame(node='n', np1='npa', np2='npb'),
  +                    trophic.links=data.frame(resource='n', consumer='n',
  +                                             tlp1='tlpa', tlp2='tlpb'),
  +                    properties=list(title='x', cp1='cpa', cp2='cpb'))
  +     y <- Community(nodes=data.frame(node='n', np1='npc'),
  +                    trophic.links=data.frame(resource='n', consumer='n',
  +                                             tlp2='tlpc'),
  +                    properties=list(title='y', cp1='cpc'))
  +     collection <- CommunityCollection(list(x,y))
  +     a <- AggregateCommunities(collection)
  +     AssertEqual(data.frame(node='n', np1='npa,npc', np2='npb', row.names='n'), NPS(a))
  +     AssertEqual(data.frame(resource='n', consumer='n', tlp1='tlpa', tlp2='tlpb,tlpc'), TLPS(a))
  +     AssertEqual('Aggregation of x,y', CPS(a)$title)
  +     AssertEqual('cpa,cpc', CPS(a)$cp1)
  +     AssertEqual('cpb', CPS(a)$cp2)
  + 
  +     # Aggregation of properties for TL84 and TL86
  +     a <- CommunityCollection(list(TL84, TL86))
  + 
  +     # tapply coerces INDEX parameter to a factor, sorting alphabetically. This 
  +     # line retains the existing ordering.
  +     a.nodes <- factor(CollectionNPS(a)[,'node'], 
  +                       levels=unique(CollectionNPS(a)[,'node']))
  + 
  +     b <- AggregateCommunities(a)
  + 
  +     # Sanity check
  +     all.spp <- sort(unique(c(NP(TL84,'node'), NP(TL86,'node'))))
  +     AssertEqual(all.spp, sort(unique(CollectionNPS(a)[,'node'])))
  +     AssertEqual(unname(sort(NP(b, 'node'))), all.spp)
  + 
  +     # Check category
  +     AssertEqual(unname(NP(b,'category')),
  +                 as.vector(tapply(CollectionNPS(a)[,'category'], a.nodes, unique)))
  + 
  +     # TODO Test that union of trophic links taken
  + }
  > 
  > TestAggregateCommunityMeans <- function()
  + {
  +     # Cases for aggregating numeric values
  + 
  +     CheckResults <- function(A, B, expected.M, expected.N, weight.by)
  +     {
  +         collection <- CommunityCollection(list(A, B))
  +         res <- NPS(AggregateCommunities(collection, weight.by=weight.by))
  +         check <- data.frame(node=c('S1','S2'), M=expected.M, N=expected.N, 
  +                             row.names=c('S1','S2'), stringsAsFactors=FALSE)
  +         AssertEqual(check, res)
  +     }
  + 
  +     # 1. Both species are in both communities. Valid M and N in both communities.
  +     #  community node  M N
  +     #         A   S1 20 1
  +     #         A   S2 20 1
  +     #         B   S1  5 2
  +     #         B   S2  5 2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c(1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5, 5), N=c(2, 2)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #     S1 10 1.5
  +     #     S2 10 1.5
  +     CheckResults(A, B, c(10,10), c(1.5, 1.5), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #     S1 12.5 1.5
  +     #     S2 12.5 1.5
  +     CheckResults(A, B, c(12.5,12.5), c(1.5, 1.5), NULL)
  + 
  + 
  +     # 2. Both species are in both communities. Species 2 lacks N in community B.
  +     #  community node  M  N
  +     #         A   S1 20  1
  +     #         A   S2 20  1
  +     #         B   S1  5  2
  +     #         B   S2  5 NA
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c( 1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5, 5), N=c( 2,NA)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #     S1 10  1.5
  +     #     S2 NA  NA
  +     CheckResults(A, B, c(10, NA), c(1.5, NA), 'N')
  + 
  +     # No weighting
  +     #   node  M    N
  +     #     S1 12.5  1.5
  +     #     S2 12.5  NA
  +     CheckResults(A, B, c(12.5, 12.5), c(1.5, NA), NULL)
  + 
  + 
  +     # 3. Both species are in both communities. Species 2 lacks M in community B
  +     #  community node  M N
  +     #         A   S1 20 1
  +     #         A   S2 20 1
  +     #         B   S1  5 2
  +     #         B   S2 NA 2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c( 1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5,NA), N=c( 2, 2)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #   S1   10  1.5
  +     #   S2   NA  1.5
  +     CheckResults(A, B, c(10, NA), c(1.5, 1.5), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1 12.5  1.5
  +     #   S2   NA  1.5
  +     CheckResults(A, B, c(12.5, NA), c(1.5, 1.5), NULL)
  + 
  + 
  +     # 4. Both species are in both communities. Species 2 lacks M and N in 
  +     #    community B
  +     #  community node  M  N
  +     #         A   S1 20  1
  +     #         A   S2 20  1
  +     #         B   S1  5  2
  +     #         B   S2 NA NA
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c( 1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5,NA), N=c( 2,NA)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #   S1   10  1.5
  +     #   S2   NA  NA
  +     CheckResults(A, B, c(10, NA), c(1.5, NA), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1 12.5  1.5
  +     #   S2   NA  NA
  +     CheckResults(A, B, c(12.5, NA), c(1.5, NA), NULL)
  + 
  +     # 5. Species 2 is in community A only. Valid M and N.
  +     #  community node  M N
  +     #         A   S1 20 1
  +     #         A   S2 20 1
  +     #         B   S1  5 2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c(1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1'),      M=c( 5),    N=c(2)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #   S1   10 1.5
  +     #   S2   20 0.5
  +     CheckResults(A, B, c(10, 20), c(1.5, 0.5), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1  12.5 1.5
  +     #   S2  10   0.5
  +     CheckResults(A, B, c(12.5, 10), c(1.5, 0.5), NULL)
  + 
  + 
  +     # 6. Species 2 is in community A only and lacks N.
  +     #  community node  M  N
  +     #         A   S1 20  1
  +     #         A   S2 20 NA
  +     #         B   S1  5  2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c(1, NA)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1'),      M=c( 5),    N=c(2)))
  +     CollectionNPS(CommunityCollection(list(A, B)))
  +     NPS(AggregateCommunities(CommunityCollection(list(A, B))))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #   S1   10 1.5
  +     #   S2   NA  NA
  +     CheckResults(A, B, c(10, NA), c(1.5, NA), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1  12.5 1.5
  +     #   S2  10   NA
  +     CheckResults(A, B, c(12.5, 10), c(1.5, NA), NULL)
  + 
  + 
  +     # 7. Species 2 is in community A only and lacks M.
  +     #  community node M N
  +     #         A   S1 20 1
  +     #         A   S2 NA 1
  +     #         B   S1  5 2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,NA), N=c(1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1'),      M=c( 5),    N=c(2)))
  +     CollectionNPS(CommunityCollection(list(A, B)))
  +     NPS(AggregateCommunities(CommunityCollection(list(A, B))))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #   S1   10  1.5
  +     #   S2   NA  0.5
  +     CheckResults(A, B, c(10, NA), c(1.5, 0.5), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1   12.5 1.5
  +     #   S2   NA   0.5
  +     CheckResults(A, B, c(12.5, NA), c(1.5, 0.5), NULL)
  + 
  + 
  +     # 8. Species 2 is in community A only and lacks M and N.
  +     #  community node  M  N
  +     #         A   S1 20  1
  +     #         A   S2 NA NA
  +     #         B   S1  5  2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,NA), N=c(1,NA)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1'),      M=c( 5),    N=c(2)))
  +     CollectionNPS(CommunityCollection(list(A, B)))
  +     NPS(AggregateCommunities(CommunityCollection(list(A, B))))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #     S1  10  1.5
  +     #     S2  NA  NA
  +     CheckResults(A, B, c(10, NA), c(1.5, NA), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1   12.5 1.5
  +     #   S2   NA   NA
  +     CheckResults(A, B, c(12.5, NA), c(1.5, NA), NULL)
  + 
  + 
  +     # 9. Both species are in both communities. Species 2 has missing M in both 
  +     #    communities
  +     #  community node  M N
  +     #         A   S1 20 1
  +     #         A   S2 NA 1
  +     #         B   S1  5 2
  +     #         B   S2 NA 2
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,NA), N=c(1, 1)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5,NA), N=c(2, 2)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #   S1  10  1.5
  +     #   S2  NA  1.5
  +     CheckResults(A, B, c(10, NA), c(1.5, 1.5), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1   12.5 1.5
  +     #   S2   NA   1.5
  +     CheckResults(A, B, c(12.5, NA), c(1.5, 1.5), NULL)
  + 
  + 
  +     # 10. Both species are in both communities. Species 2 has missing N in both 
  +     #     communities
  +     #  community node  M  N
  +     #         A   S1 20  1
  +     #         A   S2 20 NA
  +     #         B   S1  5  2
  +     #         B   S2  5 NA
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,20), N=c(1,NA)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5, 5), N=c(2,NA)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #    S1  10  1.5
  +     #    S2  NA  NA
  +     CheckResults(A, B, c(10, NA), c(1.5, NA), 'N')
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1   12.5 1.5
  +     #   S2   12.5 NA
  +     CheckResults(A, B, c(12.5, 12.5), c(1.5, NA), NULL)
  + 
  + 
  +     # 11. Both species are in both communities. Species 2 has missing M and N in 
  +     #     both communities
  +     #  community node  M  N
  +     #         A   S1 20  1
  +     #         A   S2 NA NA
  +     #         B   S1  5  2
  +     #         B   S2 NA NA
  +     A <- Community(properties=list(title='A', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c(20,NA), N=c(1,NA)))
  +     B <- Community(properties=list(title='B', M.units='g', N.units='m^-2'), 
  +                    nodes=data.frame(node=c('S1','S2'), M=c( 5,NA), N=c(2,NA)))
  + 
  +     # Weight by N
  +     #   node  M   N
  +     #    S1  10  1.5
  +     #     S2 NA  NA
  +     CheckResults(A, B, c(12.5, NA), c(1.5, NA), NULL)
  + 
  +     # No weighting
  +     #   node  M   N
  +     #   S1   12.5 1.5
  +     #   S2   NA   NA
  +     CheckResults(A, B, c(12.5, NA), c(1.5, NA), NULL)
  + }
  > 
  > TestAggregateCommunitiesBy <- function()
  + {
  +     # TODO Test these cases
  +     AggregateCommunitiesBy(pHWebs, 'pH')
  +     AggregateCommunitiesBy(pHWebs, 'lat')
  +     AggregateCommunitiesBy(pHWebs, 'NumberOfTrophicLinks')
  +     NULL
  + }
  > 
  > TestPersistCollection <- function()
  + {
  +     path <- tempfile()
  +     on.exit(unlink(path, recursive=TRUE))
  +     for(collection in list(pHWebs, Millstream))
  +     {
  +         print(collection)
  +         SaveCollection(collection, path)
  +         loaded <- LoadCollection(path)[names(collection)]
  +         AssertEqual(collection, loaded)
  +         unlink(path, recursive=TRUE)
  + 
  +         SaveCollection(collection, path, fn='write.table', sep='\t')
  +         loaded <- LoadCollection(path, fn='read.table', sep='\t')
  +         loaded <- loaded[names(collection)]
  +         AssertEqual(collection, loaded)
  +         unlink(path, recursive=TRUE)
  +     }
  + }
  > 
  > TestSiteBySpeciesMatrix <- function()
  + {
  +     res <- SiteBySpeciesMatrix(Millstream)
  +     AssertEqual(c(67,2), dim(res))
  +     AssertEqual(117, sum(res))
  +     AssertTrue(all(res %in% 0:1))
  +     AssertEqual('Valvata piscinalis', rownames(res)[67])
  +     AssertEqual(c(c4=1, d4=1), res[1,])
  +     AssertEqual(c(c4=1, d4=0), res[67,])
  + 
  +     # Same data but missing species represented by NA
  +     res <- SiteBySpeciesMatrix(Millstream, na.missing=TRUE)
  +     AssertEqual(c(67,2), dim(res))
  +     AssertEqual(117, sum(res, na.rm=TRUE))
  +     AssertTrue(all(res %in% c(NA,1)))
  +     AssertEqual('Valvata piscinalis', rownames(res)[67])
  +     AssertEqual(c(c4=1, d4=1), res[1,])
  +     AssertEqual(c(c4=1, d4=NA), res[67,])
  + 
  +     # log10 biomass abundance
  +     res <- SiteBySpeciesMatrix(Millstream, abundance='Log10Biomass', 
  +                                na.missing=TRUE)
  +     AssertEqual(c(67,2), dim(res))
  +     AssertEqual('Valvata piscinalis', rownames(res)[67])
  +     AssertEqual(c(c4=-5.0662, d4=-4.9292),res[1,])
  +     AssertEqual(c(c4=2.629, d4=NA), res[67,])
  + }
  > 
  > proc.time()
     user  system elapsed 
     0.31    0.06    0.31 
Running the tests in 'tests/community_trophic_links_test.R' failed.
Complete output:
  > # Functions requiring trophic links
  > TestPredationMatrix <- function()
  + {
  +     AssertEqual(matrix(0, ncol=1, nrow=1, dimnames=list('S', 'S')), 
  +                PredationMatrix(c1))
  +     AssertEqual(matrix(1, ncol=1, nrow=1, dimnames=list('S', 'S')), 
  +                         PredationMatrix(c2))
  +     AssertEqual(matrix(c(0,0,1,0), ncol=2, nrow=2, 
  +                                dimnames=list(c('R','C'), c('R','C'))), 
  +                         PredationMatrix(c3))
  +     AssertEqual(matrix(c(0,0,0, 1,0,0, 0,1,0), ncol=3, nrow=3, 
  +                                dimnames=list(c('R','C','P'), c('R','C','P'))), 
  +                         PredationMatrix(c4))
  +     AssertEqual(matrix(c(0,0,0, 1,0,0, 1,1,0), ncol=3, nrow=3, 
  +                                dimnames=list(c('R','C','O'), c('R','C','O'))), 
  +                         PredationMatrix(c5))
  +     AssertEqual(matrix(c(0,0,0, 1,0,0, 0,1,0), ncol=3, nrow=3, 
  +                                dimnames=list(c('R','C','P'), c('R','C','P'))), 
  +                         PredationMatrix(c6))
  +     AssertEqual(unname(NP(TL84, 'node')), rownames(PredationMatrix(TL84)))
  +     AssertEqual(unname(NP(TL84, 'node')), colnames(PredationMatrix(TL84)))
  +     AssertEqual(269, sum(PredationMatrix(TL84)))
  + }
  > 
  > TestInDegree <- function()
  + {
  +     AssertEqual(c(S=0), InDegree(c1))
  +     AssertEqual(c(S=1), InDegree(c2))
  +     AssertEqual(c(R=0,C=1), InDegree(c3))
  +     AssertEqual(c(R=0,C=1,P=1), InDegree(c4))
  +     AssertEqual(c(R=0,C=1,O=2), InDegree(c5))
  +     AssertEqual(c(R=0,C=1,P=1), InDegree(c6))
  +     AssertEqual(c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  +                   0,0,0,6,6,11,7,16,14,28,6,7,6,19,6,6,6,16,17,6,6,6,6,16,
  +                   22,9,9,12), unname(InDegree(TL84)))
  + }
  > 
  > TestNormalisedTrophicGenerality <- function()
  + {
  +     AssertEqual(c(S=NaN), NormalisedTrophicGenerality(c1))
  +     AssertEqual(c(S=1), NormalisedTrophicGenerality(c2))
  +     AssertEqual(c(R=0,C=2), NormalisedTrophicGenerality(c3))
  +     AssertEqual(c(R=0,C=1.5,P=1.5), NormalisedTrophicGenerality(c4))
  +     AssertEqual(c(R=0,C=1,O=2), NormalisedTrophicGenerality(c5))
  +     AssertEqual(c(R=0,C=1.5,P=1.5), NormalisedTrophicGenerality(c6))
  +     AssertEqual(56, sum(NormalisedTrophicGenerality(TL84)))
  +     AssertEqual( 1, mean(NormalisedTrophicGenerality(TL84)))
  + }
  > 
  > TestOutDegree <- function()
  + {
  +     AssertEqual(c(S=0), OutDegree(c1))
  +     AssertEqual(c(S=1), OutDegree(c2))
  +     AssertEqual(c(R=1,C=0), OutDegree(c3))
  +     AssertEqual(c(R=1,C=1,P=0), OutDegree(c4))
  +     AssertEqual(c(R=2,C=1,O=0), OutDegree(c5))
  +     AssertEqual(c(R=1,C=1,P=0), OutDegree(c6))
  +     AssertEqual(c(4,3,0,18,5,18,3,0,1,4,4,0,5,2,5,6,1,2,3,18,1,2,5,1,18,
  +                   0,18,0,0,1,18,5,5,4,4,7,4,4,4,4,4,3,4,5,4,7,5,4,4,4,4,
  +                   7,4,1,1,1), unname(OutDegree(TL84)))
  + }
  > 
  > TestNormalisedTrophicVulnerability <- function()
  + {
  +     AssertEqual(c(S=NaN), NormalisedTrophicVulnerability(c1))
  +     AssertEqual(c(S=1), NormalisedTrophicVulnerability(c2))
  +     AssertEqual(c(R=2,C=0), NormalisedTrophicVulnerability(c3))
  +     AssertEqual(c(R=1.5,C=1.5,P=0), NormalisedTrophicVulnerability(c4))
  +     AssertEqual(c(R=2,C=1,O=0), NormalisedTrophicVulnerability(c5))
  +     AssertEqual(c(R=1.5,C=1.5,P=0), NormalisedTrophicVulnerability(c6))
  +     AssertEqual(56, sum(NormalisedTrophicVulnerability(TL84)))
  +     AssertEqual( 1, mean(NormalisedTrophicVulnerability(TL84)))
  + }
  > 
  > TestBasalNodes <- function()
  + {
  +     AssertEqual(c(S=FALSE), IsBasalNode(c1))
  +     AssertEqual(0, length(BasalNodes(c1)))
  +     AssertEqual(c(S=FALSE), IsBasalNode(c2))
  +     AssertEqual(0, length(BasalNodes(c2)))
  +     AssertEqual(c(R=TRUE, C=FALSE), IsBasalNode(c3))
  +     AssertEqual('R', BasalNodes(c3))
  +     AssertEqual(c(R=TRUE, C=FALSE, P=FALSE), IsBasalNode(c4))
  +     AssertEqual('R', BasalNodes(c4))
  +     AssertEqual(c(R=TRUE, C=FALSE, O=FALSE), IsBasalNode(c5))
  +     AssertEqual('R', BasalNodes(c5))
  +     AssertEqual(c(R=TRUE, C=FALSE, P=FALSE), IsBasalNode(c6))
  +     AssertEqual('R', BasalNodes(c6))
  +     AssertEqual(c(A=TRUE, B=FALSE, C=FALSE, D=FALSE, E=FALSE), IsBasalNode(c7))
  +     AssertEqual('A', BasalNodes(c7))
  +     AssertEqual(c(TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,
  +                     TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,
  +                     TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,TRUE,
  +                     TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
  +                     FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
  +                     FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE), 
  +                     unname(IsBasalNode(TL84)))
  +     AssertEqual(c('Nostoc sp.','Arthrodesmus sp.','Cryptomonas sp. 1',
  +                   'Cryptomonas sp. 2','Chroococcus dispersus',
  +                   'Closteriopsis longissimus','Dinobryon bavaricum',
  +                   'Dinobryon cylindricum','Dactylococcopsis fascicularis',
  +                   'Dictyosphaerium pulchellum','Dinobryon sertularia',
  +                   'Dinobryon sociale','Glenodinium quadridens',
  +                   'Microcystis aeruginosa','Mallomonas sp. 1',
  +                   'Mallomonas sp. 2','Unclassified flagellates',
  +                   'Peridinium limbatum','Peridinium cinctum',
  +                   'Peridinium pulsillum','Peridinium wisconsinense',
  +                   'Chromulina sp.','Selenastrum minutum','Synedra sp.',
  +                   'Trachelomonas sp.'), BasalNodes(TL84))
  + }
  > 
  > TestNonBasalNodes <- function()
  + {
  +     AssertEqual(c(S=TRUE), IsNonBasalNode(c1))
  +     AssertEqual('S', NonBasalNodes(c1))
  +     AssertEqual(c(S=TRUE), IsNonBasalNode(c2))
  +     AssertEqual('S', NonBasalNodes(c2))
  +     AssertEqual(c(R=FALSE,C=TRUE), IsNonBasalNode(c3))
  +     AssertEqual('C', NonBasalNodes(c3))
  +     AssertEqual(c(R=FALSE,C=TRUE,P=TRUE), IsNonBasalNode(c4))
  +     AssertEqual(c('C','P'), NonBasalNodes(c4))
  +     AssertEqual(c(R=FALSE,C=TRUE,O=TRUE), IsNonBasalNode(c5))
  +     AssertEqual(c('C','O'), NonBasalNodes(c5))
  +     AssertEqual(c(R=FALSE,C=TRUE,P=TRUE), IsNonBasalNode(c6))
  +     AssertEqual(c('C','P'), NonBasalNodes(c6))
  +     AssertEqual(c(A=FALSE,B=TRUE,C=TRUE,D=TRUE,E=TRUE), IsNonBasalNode(c7))
  +     AssertEqual(c('B','C','D','E'), NonBasalNodes(c7))
  + }
  > 
  > TestTopLevelNodes <- function()
  + {
  +     AssertEqual(c(S=FALSE), IsTopLevelNode(c1))
  +     AssertEqual(0, length(TopLevelNodes(c1)))
  +     AssertEqual(c(S=FALSE), IsTopLevelNode(c2))
  +     AssertEqual(0, length(TopLevelNodes(c2)))
  +     AssertEqual(c(R=FALSE,C=TRUE), IsTopLevelNode(c3))
  +     AssertEqual('C', TopLevelNodes(c3))
  +     AssertEqual(c(R=FALSE,C=FALSE,P=TRUE), IsTopLevelNode(c4))
  +     AssertEqual('P', TopLevelNodes(c4))
  +     AssertEqual(c(R=FALSE,C=FALSE,O=TRUE), IsTopLevelNode(c5))
  +     AssertEqual('O', TopLevelNodes(c5))
  +     AssertEqual(c(R=FALSE,C=FALSE,P=TRUE), IsTopLevelNode(c6))
  +     AssertEqual('P', TopLevelNodes(c6))
  +     AssertEqual(c(A=FALSE,B=FALSE,C=TRUE,D=FALSE,E=FALSE), IsTopLevelNode(c7))
  +     AssertEqual('C', TopLevelNodes(c7))
  +     AssertEqual(c(rep(FALSE,55), TRUE), unname(IsTopLevelNode(TL84)))
  +     AssertEqual('Umbra limi', TopLevelNodes(TL84))
  + }
  > 
  > TestNonTopLevelNodes <- function()
  + {
  +     AssertEqual(c(S=TRUE), IsNonTopLevelNode(c1))
  +     AssertEqual('S', NonTopLevelNodes(c1))
  +     AssertEqual(c(S=TRUE), IsNonTopLevelNode(c2))
  +     AssertEqual('S', NonTopLevelNodes(c2))
  +     AssertEqual(c(R=TRUE,C=FALSE), IsNonTopLevelNode(c3))
  +     AssertEqual('R', NonTopLevelNodes(c3))
  +     AssertEqual(c(R=TRUE,C=TRUE,P=FALSE), IsNonTopLevelNode(c4))
  +     AssertEqual(c('R','C'), NonTopLevelNodes(c4))
  +     AssertEqual(c(R=TRUE,C=TRUE,O=FALSE), IsNonTopLevelNode(c5))
  +     AssertEqual(c('R','C'), NonTopLevelNodes(c5))
  +     AssertEqual(c(R=TRUE,C=TRUE,P=FALSE), IsNonTopLevelNode(c6))
  +     AssertEqual(c('R','C'), NonTopLevelNodes(c6))
  +     AssertEqual(c(A=TRUE,B=TRUE,C=FALSE,D=TRUE,E=TRUE), IsNonTopLevelNode(c7))
  +     AssertEqual(c('A','B','D','E'), NonTopLevelNodes(c7))
  +     AssertEqual(c(rep(TRUE,55), FALSE), unname(IsNonTopLevelNode(TL84)))
  +     AssertEqual(c('Nostoc sp.','Arthrodesmus sp.','Asterionella formosa',
  +                   'Cryptomonas sp. 1','Cryptomonas sp. 2',
  +                   'Chroococcus dispersus','Closteriopsis longissimus',
  +                   'Chrysosphaerella longispina','Dinobryon bavaricum',
  +                   'Dinobryon cylindricum','Dactylococcopsis fascicularis',
  +                   'Diceras sp.','Dictyosphaerium pulchellum',
  +                   'Dinobryon sertularia','Dinobryon sociale',
  +                   'Glenodinium quadridens','Microcystis aeruginosa',
  +                   'Mallomonas sp. 1','Mallomonas sp. 2',
  +                   'Unclassified flagellates','Peridinium limbatum',
  +                   'Peridinium cinctum','Peridinium pulsillum',
  +                   'Peridinium wisconsinense','Chromulina sp.',
  +                   'Rhizosolenia sp.','Selenastrum minutum',
  +                   'Spinocosmarium sp.','Staurastrum sp.','Synedra sp.',
  +                   'Trachelomonas sp.','Ascomorpha eucadis','Synchaeta sp.',
  +                   'Bosmina longirostris','Conochilus (solitary)',
  +                   'Cyclops varians rubellus',
  +                   'Diaphanosoma leuchtenbergianum','Daphnia pulex',
  +                   'Filinia longispina','Conochiloides dossuarius',
  +                   'Gastropus stylifer','Holopedium gibberum',
  +                   'Kellicottia sp.','Keratella cochlearis',
  +                   'Keratella testudo','Leptodiaptomus siciloides',
  +                   'Orthocyclops modestus','Ploesoma sp.',
  +                   'Polyarthra vulgaris','Trichocerca multicrinis',
  +                   'Trichocerca cylindrica','Tropocyclops prasinus',
  +                   'Chaoborus punctipennis','Phoxinus eos',
  +                   'Phoxinus neogaeus'), NonTopLevelNodes(TL84))
  + }
  > 
  > TestIntermediateNodes <- function()
  + {
  +     AssertEqual(c(S=FALSE), IsIntermediateNode(c1))
  +     AssertEqual(0, length(IntermediateNodes(c1)))
  +     AssertEqual(c(S=FALSE), IsIntermediateNode(c2))
  +     AssertEqual(0, length(IntermediateNodes(c2)))
  +     AssertEqual(c(R=FALSE,C=FALSE), IsIntermediateNode(c3))
  +     AssertEqual(0, length(IntermediateNodes(c3)))
  +     AssertEqual(c(R=FALSE,C=TRUE,P=FALSE), IsIntermediateNode(c4))
  +     AssertEqual('C', IntermediateNodes(c4))
  +     AssertEqual(c(R=FALSE,C=TRUE,O=FALSE), IsIntermediateNode(c5))
  +     AssertEqual('C', IntermediateNodes(c5))
  +     AssertEqual(c(R=FALSE,C=TRUE,P=FALSE), IsIntermediateNode(c6))
  +     AssertEqual('C', IntermediateNodes(c6))
  +     AssertEqual(c(A=FALSE,B=TRUE,C=FALSE,D=FALSE,E=FALSE), IsIntermediateNode(c7))
  +     AssertEqual('B', IntermediateNodes(c7))
  +     AssertEqual(c(rep(FALSE,31), rep(TRUE,24), FALSE), 
  +                 unname(IsIntermediateNode(TL84)))
  +     AssertEqual(c('Ascomorpha eucadis','Synchaeta sp.',
  +                   'Bosmina longirostris','Conochilus (solitary)',
  +                   'Cyclops varians rubellus',
  +                   'Diaphanosoma leuchtenbergianum','Daphnia pulex',
  +                   'Filinia longispina','Conochiloides dossuarius',
  +                   'Gastropus stylifer','Holopedium gibberum',
  +                   'Kellicottia sp.','Keratella cochlearis',
  +                   'Keratella testudo','Leptodiaptomus siciloides',
  +                   'Orthocyclops modestus','Ploesoma sp.',
  +                   'Polyarthra vulgaris','Trichocerca multicrinis',
  +                   'Trichocerca cylindrica','Tropocyclops prasinus',
  +                   'Chaoborus punctipennis','Phoxinus eos',
  +                   'Phoxinus neogaeus'), 
  +                 IntermediateNodes(TL84))
  + }
  > 
  > TestIsolatedNodes <- function()
  + {
  +     AssertEqual(c(S=TRUE), IsIsolatedNode(c1))
  +     AssertEqual('S', IsolatedNodes(c1))
  +     AssertEqual(c(S=TRUE), IsIsolatedNode(c2))
  +     AssertEqual('S', IsolatedNodes(c2)) # Cannibalism ignored
  +     AssertEqual(c(R=FALSE,C=FALSE), IsIsolatedNode(c3))
  +     AssertEqual(0, length(IsolatedNodes(c3)))
  +     AssertEqual(c(R=FALSE,C=FALSE,P=FALSE), IsIsolatedNode(c4))
  +     AssertEqual(0, length(IsolatedNodes(c4)))
  +     AssertEqual(c(R=FALSE,C=FALSE,O=FALSE), IsIsolatedNode(c5))
  +     AssertEqual(0, length(IsolatedNodes(c5)))
  +     AssertEqual(c(R=FALSE,C=FALSE,P=FALSE), IsIsolatedNode(c6))
  +     AssertEqual(0, length(IsolatedNodes(c6)))
  +     AssertEqual(c(A=FALSE,B=FALSE,C=FALSE,D=TRUE,E=TRUE), IsIsolatedNode(c7))
  +     AssertEqual(c('D','E'), IsolatedNodes(c7))
  +     target <- rep(FALSE, 56)
  +     target[c(3,8,12,26,28,29)] <- TRUE
  +     AssertEqual(target, unname(IsIsolatedNode(TL84)))
  +     AssertEqual(c('Asterionella formosa','Chrysosphaerella longispina',
  +                   'Diceras sp.', 'Rhizosolenia sp.', 'Spinocosmarium sp.',
  +                   'Staurastrum sp.'), IsolatedNodes(TL84))
  + }
  > 
  > TestConnectedNodes <- function()
  + {
  +     AssertEqual(c(S=FALSE), IsConnectedNode(c1))
  +     AssertEqual(0, length(ConnectedNodes(c1)))
  +     AssertEqual(c(S=FALSE), IsConnectedNode(c2))
  +     AssertEqual(0, length(ConnectedNodes(c2))) # Cannibalism ignored
  +     AssertEqual(c(R=TRUE,C=TRUE), IsConnectedNode(c3))
  +     AssertEqual(c('R','C'), ConnectedNodes(c3))
  +     AssertEqual(c(R=TRUE,C=TRUE,P=TRUE), IsConnectedNode(c4))
  +     AssertEqual(c('R','C','P'), ConnectedNodes(c4))
  +     AssertEqual(c(R=TRUE,C=TRUE,O=TRUE), IsConnectedNode(c5))
  +     AssertEqual(c('R','C','O'), ConnectedNodes(c5))
  +     AssertEqual(c(R=TRUE,C=TRUE,P=TRUE), IsConnectedNode(c6))
  +     AssertEqual(c('R','C','P'), ConnectedNodes(c6))
  +     AssertEqual(c(A=TRUE,B=TRUE,C=TRUE,D=FALSE,E=FALSE), IsConnectedNode(c7))
  +     AssertEqual(c('A','B','C'), ConnectedNodes(c7))
  +     target <- rep(TRUE, 56)
  +     target[c(3,8,12,26,28,29)] <- FALSE
  +     AssertEqual(target, unname(IsConnectedNode(TL84)))
  +     AssertEqual(c('Nostoc sp.','Arthrodesmus sp.','Cryptomonas sp. 1',
  +                   'Cryptomonas sp. 2','Chroococcus dispersus',
  +                   'Closteriopsis longissimus','Dinobryon bavaricum',
  +                   'Dinobryon cylindricum','Dactylococcopsis fascicularis',
  +                   'Dictyosphaerium pulchellum','Dinobryon sertularia',
  +                   'Dinobryon sociale','Glenodinium quadridens',
  +                   'Microcystis aeruginosa','Mallomonas sp. 1',
  +                   'Mallomonas sp. 2','Unclassified flagellates',
  +                   'Peridinium limbatum','Peridinium cinctum',
  +                   'Peridinium pulsillum','Peridinium wisconsinense',
  +                   'Chromulina sp.','Selenastrum minutum','Synedra sp.',
  +                   'Trachelomonas sp.','Ascomorpha eucadis','Synchaeta sp.',
  +                   'Bosmina longirostris','Conochilus (solitary)',
  +                   'Cyclops varians rubellus',
  +                   'Diaphanosoma leuchtenbergianum','Daphnia pulex',
  +                   'Filinia longispina','Conochiloides dossuarius',
  +                   'Gastropus stylifer','Holopedium gibberum',
  +                   'Kellicottia sp.','Keratella cochlearis',
  +                   'Keratella testudo','Leptodiaptomus siciloides',
  +                   'Orthocyclops modestus','Ploesoma sp.',
  +                   'Polyarthra vulgaris','Trichocerca multicrinis',
  +                   'Trichocerca cylindrica','Tropocyclops prasinus',
  +                   'Chaoborus punctipennis','Phoxinus eos',
  +                   'Phoxinus neogaeus','Umbra limi'), ConnectedNodes(TL84))
  + }
  > 
  > TestFractionBasalNodes <- function()
  + {
  +     AssertEqual(0, FractionBasalNodes(c1))
  +     AssertEqual(0, FractionBasalNodes(c2))
  +     AssertEqual(0.5, FractionBasalNodes(c3))
  +     AssertEqual(1/3, FractionBasalNodes(c4))
  +     AssertEqual(1/3, FractionBasalNodes(c5))
  +     AssertEqual(1/3, FractionBasalNodes(c6))
  +     AssertEqual(1/5, FractionBasalNodes(c7))
  +     AssertEqual(25/56, FractionBasalNodes(TL84))
  + }
  > 
  > TestFractionNonBasalNodes <- function()
  + {
  +     AssertEqual(1, FractionNonBasalNodes(c1))
  +     AssertEqual(1, FractionNonBasalNodes(c2))
  +     AssertEqual(0.5, FractionNonBasalNodes(c3))
  +     AssertEqual(2/3, FractionNonBasalNodes(c4))
  +     AssertEqual(2/3, FractionNonBasalNodes(c5))
  +     AssertEqual(2/3, FractionNonBasalNodes(c6))
  +     AssertEqual(4/5, FractionNonBasalNodes(c7))
  +     AssertEqual(31/56, FractionNonBasalNodes(TL84))
  + }
  > 
  > TestFractionIntermediateNodes <- function()
  + {
  +     AssertEqual(0, FractionIntermediateNodes(c1))
  +     AssertEqual(0, FractionIntermediateNodes(c2))
  +     AssertEqual(0, FractionIntermediateNodes(c3))
  +     AssertEqual(1/3, FractionIntermediateNodes(c4))
  +     AssertEqual(1/3, FractionIntermediateNodes(c5))
  +     AssertEqual(1/3, FractionIntermediateNodes(c6))
  +     AssertEqual(1/5, FractionIntermediateNodes(c7))
  +     AssertEqual(24/56, FractionIntermediateNodes(TL84))
  + }
  > 
  > TestFractionTopLevelNodes <- function()
  + {
  +     AssertEqual(0, FractionTopLevelNodes(c1))
  +     AssertEqual(0, FractionTopLevelNodes(c2))
  +     AssertEqual(0.5, FractionTopLevelNodes(c3))
  +     AssertEqual(1/3, FractionTopLevelNodes(c4))
  +     AssertEqual(1/3, FractionTopLevelNodes(c5))
  +     AssertEqual(1/3, FractionTopLevelNodes(c6))
  +     AssertEqual(1/5, FractionTopLevelNodes(c7))
  +     AssertEqual(1/56, FractionTopLevelNodes(TL84))
  + }
  > 
  > TestFractionNonTopLevelNodes <- function()
  + {
  +     AssertEqual(1, FractionNonTopLevelNodes(c1))
  +     AssertEqual(1, FractionNonTopLevelNodes(c2))
  +     AssertEqual(0.5, FractionNonTopLevelNodes(c3))
  +     AssertEqual(2/3, FractionNonTopLevelNodes(c4))
  +     AssertEqual(2/3, FractionNonTopLevelNodes(c5))
  +     AssertEqual(2/3, FractionNonTopLevelNodes(c6))
  +     AssertEqual(4/5, FractionNonTopLevelNodes(c7))
  +     AssertEqual(55/56, FractionNonTopLevelNodes(TL84))
  + }
  > 
  > TestFractionIsolatedNodes <- function()
  + {
  +     AssertEqual(1, FractionIsolatedNodes(c1))
  +     AssertEqual(1, FractionIsolatedNodes(c2))
  +     AssertEqual(0, FractionIsolatedNodes(c3))
  +     AssertEqual(0, FractionIsolatedNodes(c4))
  +     AssertEqual(0, FractionIsolatedNodes(c5))
  +     AssertEqual(0, FractionIsolatedNodes(c6))
  +     AssertEqual(2/5, FractionIsolatedNodes(c7))
  +     AssertEqual(6/56, FractionIsolatedNodes(TL84))
  + }
  > 
  > TestFractionConnectedNodes <- function()
  + {
  +     AssertEqual(0, FractionConnectedNodes(c1))
  +     AssertEqual(0, FractionConnectedNodes(c2))
  +     AssertEqual(1, FractionConnectedNodes(c3))
  +     AssertEqual(1, FractionConnectedNodes(c4))
  +     AssertEqual(1, FractionConnectedNodes(c5))
  +     AssertEqual(1, FractionConnectedNodes(c6))
  +     AssertEqual(3/5, FractionConnectedNodes(c7))
  +     AssertEqual(50/56, FractionConnectedNodes(TL84))
  + }
  > 
  > TestFractions <- function()
  + {
  +     # These should sum to 1
  +     for(community in list(c1,c2,c3,c4,c5,c6,c7,TL84))
  +     {
  +         print(community)
  +         AssertEqual(1, sum(FractionBasalNodes(community), 
  +                            FractionIntermediateNodes(community), 
  +                            FractionTopLevelNodes(community), 
  +                            FractionIsolatedNodes(community)))
  + 
  +         AssertEqual(1, sum(FractionConnectedNodes(community), 
  +                            FractionIsolatedNodes(community)))
  + 
  +         AssertEqual(1, sum(FractionBasalNodes(community), 
  +                            FractionNonBasalNodes(community)))
  + 
  +         AssertEqual(1, sum(FractionTopLevelNodes(community), 
  +                            FractionNonTopLevelNodes(community)))
  +     }
  + }
  > 
  > TestResourcesByNode <- function()
  + {
  +     AssertEqual(list(S=vector('character')), ResourcesByNode(c1))
  +     AssertEqual(list(S='S'), ResourcesByNode(c2))
  +     AssertEqual(list(R=vector('character'), C='R'), ResourcesByNode(c3))
  +     AssertEqual(list(R=vector('character'), C='R', P='C'), ResourcesByNode(c4))
  +     AssertEqual(list(R=vector('character'), C='R', O=c('R','C')), 
  +                 ResourcesByNode(c5))
  +     AssertEqual(list(R=vector('character'), C='R', P='C'), ResourcesByNode(c6))
  + }
  > 
  > TestResourcesOfNodes <- function()
  + {
  +     AssertEqual(vector('character'), ResourcesOfNodes(c1, 'S'))
  +     AssertEqual('S', ResourcesOfNodes(c2, 'S'))
  +     AssertEqual(vector('character'), ResourcesOfNodes(c3, 'R'))
  +     AssertEqual('R', ResourcesOfNodes(c3, 'C'))
  +     AssertEqual(vector('character'), ResourcesOfNodes(c4, 'R'))
  +     AssertEqual('R', ResourcesOfNodes(c4, 'C'))
  +     AssertEqual('C', ResourcesOfNodes(c4, 'P'))
  + 
  +     # More than one node
  +     AssertEqual(list(R=vector('character'), C='R'), 
  +                         ResourcesOfNodes(c4, c('R','C')))
  +     AssertEqual(list(R=vector('character'), C='R'), 
  +                         ResourcesOfNodes(c4, 1:2))
  + 
  +     # Bad nodes
  +     AssertRaises(ResourcesOfNodes(c1, 0))
  +     AssertRaises(ResourcesOfNodes(c1, 2))
  +     AssertRaises(ResourcesOfNodes(c1, ''))
  +     AssertRaises(ResourcesOfNodes(c1, 'x'))
  + }
  > 
  > TestConsumersByNode <- function()
  + {
  +     AssertEqual(list(S=vector('character')), ConsumersByNode(c1))
  +     AssertEqual(list(S='S'), ConsumersByNode(c2))
  +     AssertEqual(list(R='C', C=vector('character')), 
  +                         ConsumersByNode(c3))
  +     AssertEqual(list(R='C', C='P', P=vector('character')), 
  +                         ConsumersByNode(c4))
  +     AssertEqual(list(R=c('C','O'), C='O', O=vector('character')), 
  +                         ConsumersByNode(c5))
  +     AssertEqual(list(R='C', C='P', P=vector('character')), 
  +                         ConsumersByNode(c6))
  + }
  > 
  > TestConsumersOfNodes <- function()
  + {
  +     AssertEqual(vector('character'), ConsumersOfNodes(c1, 'S'))
  +     AssertEqual('S', ConsumersOfNodes(c2, 'S'))
  +     AssertEqual('C', ConsumersOfNodes(c3, 'R'))
  +     AssertEqual(vector('character'), ConsumersOfNodes(c3, 'C'))
  +     AssertEqual('C', ConsumersOfNodes(c4, 'R'))
  +     AssertEqual('P', ConsumersOfNodes(c4, 'C'))
  +     AssertEqual(vector('character'), ConsumersOfNodes(c4, 'P'))
  + 
  +     # More than one node
  +     AssertEqual(list(R='C', C='P'), 
  +                         ConsumersOfNodes(c4, c('R','C')))
  +     AssertEqual(list(R='C', C='P'), 
  +                         ConsumersOfNodes(c4, 1:2))
  + 
  +     # Bad nodes
  +     AssertRaises(ConsumersOfNodes(c1, 0))
  +     AssertRaises(ConsumersOfNodes(c1, 2))
  +     AssertRaises(ConsumersOfNodes(c1, ''))
  +     AssertRaises(ConsumersOfNodes(c1, 'x'))
  + }
  > 
  > TestResourcesAndConsumersByNode <- function()
  + {
  +     AssertEqual(list(S=vector('character')), ResourcesAndConsumersByNode(c1))
  +     AssertEqual(list(S='S'), ResourcesAndConsumersByNode(c2))
  +     AssertEqual(list(R='C', C='R'), ResourcesAndConsumersByNode(c3))
  +     AssertEqual(list(R='C', C=c('R','P'), P='C'), 
  +                 ResourcesAndConsumersByNode(c4))
  +     AssertEqual(list(R=c('C','O'), C=c('R','O'), O=c('R','C')), 
  +                 ResourcesAndConsumersByNode(c5))
  +     AssertEqual(list(R='C', C=c('R','P'), P='C'), 
  +                 ResourcesAndConsumersByNode(c6))
  +     AssertEqual(list(A=c('A','B'), B=c('A','C'), C=c('B','C'), D='D', 
  +                      E=vector(mode='character')), 
  +                 ResourcesAndConsumersByNode(c7))
  + }
  > 
  > TestNumberOfTrophicLinks <- function()
  + {
  +     AssertEqual(0, NumberOfTrophicLinks(c1))
  +     AssertEqual(1, NumberOfTrophicLinks(c2))
  +     AssertEqual(1, NumberOfTrophicLinks(c3))
  +     AssertEqual(2, NumberOfTrophicLinks(c4))
  +     AssertEqual(3, NumberOfTrophicLinks(c5))
  +     AssertEqual(2, NumberOfTrophicLinks(c6))
  +     AssertEqual(5, NumberOfTrophicLinks(c7))
  +     AssertEqual(5, NumberOfTrophicLinks(c7))
  +     AssertEqual(269, NumberOfTrophicLinks(TL84))
  +     AssertEqual(264, NumberOfTrophicLinks(RemoveCannibalisticLinks(TL84)))
  + }
  > 
  > TestLinkageDensity <- function()
  + {
  +     AssertEqual(0, LinkageDensity(c1))
  +     AssertEqual(1, LinkageDensity(c2))
  +     AssertEqual(0.5, LinkageDensity(c3))
  +     AssertEqual(2/3, LinkageDensity(c4))
  +     AssertEqual(1, LinkageDensity(c5))
  +     AssertEqual(4.80357142857142882519, LinkageDensity(TL84))
  + }
  > 
  > TestDegree <- function()
  + {
  +     AssertEqual(c(S=0), Degree(c1))
  +     AssertEqual(c(S=2), Degree(c2))
  +     AssertEqual(InDegree(c2)+OutDegree(c2), Degree(c2))
  +     AssertEqual(c(R=1,C=1), Degree(c3))
  +     AssertEqual(InDegree(c3)+OutDegree(c3), Degree(c3))
  +     AssertEqual(c(R=1,C=2,P=1), Degree(c4))
  +     AssertEqual(InDegree(c4)+OutDegree(c4), Degree(c4))
  +     AssertEqual(c(R=2,C=2,O=2), Degree(c5))
  +     AssertEqual(InDegree(c5)+OutDegree(c5), Degree(c5))
  +     AssertEqual(c(4,3,0,18,5,18,3,0,1,4,4,0,5,2,5,6,1,2,3,18,1,2,5,1,
  +                   18,0,18,0,0,1,18,11,11,15,11,23,18,32,10,11,10,22,10,
  +                   11,10,23,22,10,10,10,10,23,26,10,10,13), unname(Degree(TL84)))
  +     AssertEqual(InDegree(TL84)+OutDegree(TL84), Degree(TL84))
  + }
  > 
  > TestDegreeDistribution <- function()
  + {
  +     AssertEqual(c('0'=1), DegreeDistribution(c1))
  +     AssertEqual(c('0'=0, '1'=0, '2'=1), DegreeDistribution(c2))
  +     AssertEqual(c('0'=0, '1'=1), DegreeDistribution(c3))
  +     AssertEqual(c('0'=0, '1'=2/3, '2'=1/3), DegreeDistribution(c4))
  +     AssertEqual(c('0'=0, '1'=0, '2'=1), DegreeDistribution(c5))
  +     AssertEqual(c('0'=0, '1'=2/3, '2'=1/3), DegreeDistribution(c6))
  + }
  > 
  > TestDirectedConnectance <- function()
  + {
  +     AssertEqual(0, DirectedConnectance(c1))
  +     AssertEqual(1, DirectedConnectance(c2))
  +     AssertEqual(0.25, DirectedConnectance(c3))
  +     AssertEqual(2/9, DirectedConnectance(c4))
  +     AssertEqual(1/3, DirectedConnectance(c5))
  +     AssertEqual(0.08577806122448979054, DirectedConnectance(TL84))
  + }
  > 
  > TestCannibals <- function()
  + {
  +     AssertEqual(c(S=FALSE), IsCannibal(c1))
  +     AssertEqual(0, length(Cannibals(c1)))
  +     AssertEqual(0, FractionCannibalistic(c1))
  +     AssertEqual(c(S=TRUE), IsCannibal(c2))
  +     AssertEqual('S', Cannibals(c2))
  +     AssertEqual(1, FractionCannibalistic(c2))
  +     AssertEqual(c(R=FALSE,C=FALSE), IsCannibal(c3))
  +     AssertEqual(0, length(Cannibals(c3)))
  +     AssertEqual(0, FractionCannibalistic(c3))
  +     AssertEqual(c(R=FALSE,C=FALSE,P=FALSE), IsCannibal(c4))
  +     AssertEqual(0, length(Cannibals(c4)))
  +     AssertEqual(0, FractionCannibalistic(c4))
  +     AssertEqual(c(R=FALSE,C=FALSE,O=FALSE), IsCannibal(c5))
  +     AssertEqual(0, length(Cannibals(c5)))
  +     AssertEqual(0, FractionCannibalistic(c5))
  +     AssertEqual(c(A=TRUE,B=FALSE,C=TRUE,D=TRUE,E=FALSE), IsCannibal(c7))
  +     AssertEqual(c('A','C','D'), Cannibals(c7))
  +     AssertEqual(3/5, FractionCannibalistic(c7))
  +     AssertEqual(c("Cyclops varians rubellus", "Orthocyclops modestus",
  +                   "Tropocyclops prasinus", "Chaoborus punctipennis", 
  +                   "Umbra limi"), Cannibals(TL84))
  +     AssertEqual(5/56, FractionCannibalistic(TL84))
  + }
  > 
  > TestTrophicChainsStats <- function()
  + {
  +     AssertEqual(NULL, TrophicChainsStats(c1))
  +     AssertEqual(NULL, TrophicChainsStats(c2))
  +     AssertEqual(1, TrophicChainsStats(c3)$chain.lengths)
  +     AssertEqual(matrix(c(1,0,0,1), nrow=2, dimnames=list(c('R','C'), NULL)), 
  +                 TrophicChainsStats(c3)$node.pos.counts)
  +     AssertEqual(2, TrophicChainsStats(c4)$chain.lengths)
  +     AssertEqual(matrix(c(1,0,0,0,1,0,0,0,1), nrow=3, 
  +                        dimnames=list(c('R','C','P'), NULL)), 
  +                 TrophicChainsStats(c4)$node.pos.counts)
  +     AssertEqual(c(1,2), TrophicChainsStats(c5)$chain.lengths)
  +     AssertEqual(matrix(c(2,0,0,0,1,1,0,0,1), nrow=3, 
  +                        dimnames=list(c('R','C','O'), NULL)), 
  +                 TrophicChainsStats(c5)$node.pos.counts)
  +     AssertEqual(2, TrophicChainsStats(c6)$chain.lengths)
  +     AssertEqual(matrix(c(1,0,0,0,1,0,0,0,1), nrow=3, 
  +                        dimnames=list(c('R','C','P'), NULL)), 
  +                 TrophicChainsStats(c6)$node.pos.counts)
  +     AssertEqual(2, TrophicChainsStats(c7)$chain.lengths)
  +     AssertEqual(matrix(c(1,0,0,0,0,0,1,0,0,0,0,0,1,0,0), nrow=5, 
  +                        dimnames=list(c('A','B','C','D','E'), NULL)), 
  +                 TrophicChainsStats(c7)$node.pos.counts)
  + 
  +     # Simpler tests for larger communities                              sum pos 
  +     #                       Mean chain length       n.chains, longest   count
  +     to.test <- list(
  +       list(TL84,             4.83500334001336007361,    5988,   8,      34940), 
  +       list(TL86,             4.84470882905447730593,    1597,   7,       9334), 
  +       list(YthanEstuary,     5.08319118225954635903,    7621,  10,      46360), 
  +       list(SkipwithPond,    10.4850243487305565537,  2538120,  17,   29150370), 
  +       list(BroadstoneStream, 5.63949610967024828057,    5398,  10,      35840))
  +     for(index in 1:length(to.test))
  +     {
  +         community <- to.test[[index]][[1]]
  +         print(community)
  + 
  +         s <- TrophicChainsStats(community)
  +         AssertEqual(to.test[[index]][[2]], mean(s$chain.lengths))
  +         AssertEqual(to.test[[index]][[3]], length(s$chain.length))
  +         AssertEqual(to.test[[index]][[4]], ncol(s$node.pos.counts))
  +         AssertEqual(to.test[[index]][[5]], sum(s$node.pos.counts))
  +     }
  + }
  > 
  > TestTrophicChainsStatsOverflow <- function()
  + {
  +     community <- TL84
  +     alist <- cheddar:::.CAdjacencyList(community, ConsumersByNode(community))
  + 
  +     # 1 if basal, 0 otherwise
  +     is.basal <- as.integer(IsBasalNode(community))
  + 
  +     # Outputs to be filled by the C function
  +     n.chains <- as.integer(0)
  +     longest <- as.integer(0)
  +     status <- as.integer(-1)
  + 
  +     res <- .C('trophic_chains_size', 
  +               as.integer(alist), 
  +               as.integer(length(alist)), 
  +               as.integer(is.basal), 
  +               as.integer(nrow(alist)), 
  +               as.integer(1), # test_overflow
  +               as.integer(0), # max_queue
  +               n.chains=n.chains,
  +               longest=longest,
  +               status=status, 
  +               PACKAGE='cheddar', NAOK=TRUE, DUP=FALSE)
  + 
  +     AssertEqual(-1, res$status)
  + }
  > 
  > TestTrophicChains <- function()
  + {
  +     CheckChains <- function(community, chains)
  +     {
  +         # Helper function
  +         # Chains of length 1 would indicate isolated node
  +         AssertEqual(FALSE, any(1==apply(chains, 1, function(r) sum(''!=r))))
  + 
  +         # Should be no duplicated rows
  +         AssertEqual(FALSE, any(duplicated(chains, MARGIN=1)))
  + 
  +         # No node should appear more than once in a chain
  +         AssertEqual(FALSE, 
  +                    any(apply(chains, 1, function(r) any(duplicated(r[''!=r])))))
  + 
  +         # Each chain should start with a basal node
  +         AssertEqual(TRUE, all(chains[,1] %in% BasalNodes(community)))
  + 
  +         if(any(IsTopLevelNode(community)))
  +         {
  +             # Each chain should end with a top-level node
  +             last <- apply(chains, 1, function(row) row[max(which(""!=row))])
  +             AssertEqual(TRUE, all(last %in% TopLevelNodes(community)))
  +         }
  + 
  +         # Make sure that every link in every chain appears in the predation 
  +         # matrix
  +         pm <- PredationMatrix(community)
  +         apply(chains, 1, function(chain)
  +         {
  +             last.in.chain <- tail(which(''!=chain), 1)
  +             from <- chain[1:(last.in.chain-1)]
  +             to <- chain[2:last.in.chain]
  +             AssertEqual(rep(1, length(to)), as.vector(diag(pm[from,to])))
  +         })
  + 
  +         # How could this not be the case?
  +         AssertEqual(TRUE, ncol(chains)<=NumberOfNodes(community))
  +     }
  + 
  +     # Some extra test cases
  +     test1 <- Community(nodes=data.frame(node=c('A', 'B', 'C')), 
  +                        trophic.links=cbind(resource=c('A', 'B', 'C'), 
  +                                            consumer=c('B', 'C', 'B')), 
  +                        properties=list(title='test1'))
  + 
  +     test2 <- Community(nodes=data.frame(node=c('A', 'B', 'C')), 
  +                        trophic.links=cbind(resource=c('A', 'B', 'A', 'C'), 
  +                                            consumer=c('B', 'C', 'C', 'B')), 
  +                        properties=list(title='test2'))
  + 
  +     test3 <- Community(nodes=data.frame(node=c('A', 'B', 'C')), 
  +                        trophic.links=cbind(resource=c('A', 'B', 'A'), 
  +                                            consumer=c('B', 'C', 'C')), 
  +                        properties=list(title='test2'))
  + 
  + 
  +     to.test <- list(list(c1,NULL), 
  +       list(c2,NULL), 
  +       list(c3,data.frame(Node.1='R',Node.2='C', stringsAsFactors=FALSE)), 
  +       list(c4,data.frame(Node.1='R',Node.2='C',Node.3='P', stringsAsFactors=FALSE)), 
  +       list(c5,data.frame(Node.1=c('R','R'), 
  +                          Node.2=c('O','C'), 
  +                          Node.3=c('', 'O'), stringsAsFactors=FALSE)), 
  +       list(c6,data.frame(Node.1='R',Node.2='C',Node.3='P', stringsAsFactors=FALSE)), 
  +       list(c7,data.frame(Node.1='A',Node.2='B',Node.3='C', stringsAsFactors=FALSE)),
  +       list(test1,data.frame(Node.1='A',Node.2='B',Node.3='C', stringsAsFactors=FALSE)), 
  +       list(test2,data.frame(Node.1=c('A','A'),
  +                             Node.2=c('B','C'), 
  +                             Node.3=c('C','B'), stringsAsFactors=FALSE)),
  +       list(test3,data.frame(Node.1=c('A','A'),
  +                             Node.2=c('C','B'), 
  +                             Node.3=c( '','C'), stringsAsFactors=FALSE)))
  +     for(index in 1:length(to.test))
  +     {
  +         community <- to.test[[index]][[1]]
  +         expected <- to.test[[index]][[2]]
  +         print(community)
  + 
  +         chains <- TrophicChains(community)
  +         AssertEqual(expected, chains)
  +         if(!is.null(chains))
  +         {
  +             CheckChains(community, chains)
  +         }
  +     }
  + 
  +     # Webs with many nodes - don't check each link, just dims and first chain
  +     to.test <- list(
  +       list(TL84, c(5988, 8), list('Nostoc sp.','Diaphanosoma leuchtenbergianum',
  +                                   'Umbra limi')),
  +       list(TL86, c(1597, 7), list('Ankyra judayi','Daphnia rosea',
  +                                   'Chaoborus punctipennis',
  +                                   'Micropterus salmoides')),
  +       list(YthanEstuary, c(7621, 10), list('Diatoms','Crangon crangon',
  +                                            'Somateria mollissima')),
  +       list(BroadstoneStream, c(5398, 10), list('Potamophylax cingulatus', 
  +                                                'Cordulegaster boltonii')), 
  +       list(Benguela, c(15430, 14), list('Phytoplankton', 'Anchovy', 'Seals', 
  +                                         'Sharks')))
  +     to.test <- head(to.test, -1)
  + 
  +     for(index in 1:length(to.test))
  +     {
  +         community <- to.test[[index]][[1]]
  +         expected.dim <- to.test[[index]][[2]]
  +         expected.first.chain <- to.test[[index]][[3]]
  +         print(community)
  + 
  +         chains <- TrophicChains(community)
  +         AssertEqual(expected.dim, dim(chains))
  +         AssertEqual(expected.first.chain, 
  +                     unname(chains[1,1:length(expected.first.chain),drop=TRUE]))
  +         CheckChains(community, chains)
  +     }
  + }
  > 
  > TestThreeNodeChains <- function()
  + {
  +     CheckChains <- function(community, chains)
  +     {
  +         # Helper function
  +         # Sanity checks
  +         # Should be no duplicated rows
  +         AssertEqual(FALSE, any(duplicated(chains, MARGIN=1)))
  + 
  +         # No node should appear more than once in a chain except as bottom and 
  +         # top.
  +         AssertEqual(FALSE, 
  +                     any(apply(chains, 1, function(r) r[1]==r[2] | r[2]==r[3])))
  + 
  +         # Make sure that every link in every chain appears in the predation 
  +         # matrix
  +         pm <- PredationMatrix(community)
  +         apply(chains, 1, function(chain)
  +         {
  +             from <- head(chain, -1)
  +             to <- tail(chain, -1)
  +             AssertEqual(rep(1, length(to)), diag(pm[from,to]))
  +         })
  +     }
  + 
  +     to.test <- list(
  +       list(c1, NULL), 
  +       list(c2, NULL), 
  +       list(c3, NULL), 
  +       list(c4, data.frame(bottom='R',intermediate='C',top='P')), 
  +       list(c5, data.frame(bottom='R',intermediate='C',top='O')), 
  +       list(c6, data.frame(bottom='R',intermediate='C',top='P')),
  +       list(c7, data.frame(bottom='A',intermediate='B',top='C')))
  +     for(index in 1:length(to.test))
  +     {
  +         community <- to.test[[index]][[1]]
  +         expected <- to.test[[index]][[2]]
  +         print(community)
  + 
  +         chains <- ThreeNodeChains(community)
  +         AssertEqual(expected, chains)
  +         if(!is.null(chains))
  +         {
  +             CheckChains(community, chains)
  +         }
  + 
  +         chains <- ThreeNodeChains(community, exclude.loops=TRUE)
  +         AssertEqual(expected, chains)
  +         if(!is.null(chains))
  +         {
  +             CheckChains(community, chains)
  +         }
  +     }
  + 
  +     # Webs with many nodes - don't check each link, just nrows
  +     to.test <- list(list(TL84, 1044, 1042), 
  +                     list(TL86, 651, 645),
  +                     list(YthanEstuary, 1616, 1616),
  +                     list(SkipwithPond, 2433, 2401))
  +     for(index in 1:length(to.test))
  +     {
  +         community <- to.test[[index]][[1]]
  +         expected.rows <- to.test[[index]][[2]]
  +         expected.rows.no.loops <- to.test[[index]][[3]]
  +         print(community)
  + 
  +         chains <- ThreeNodeChains(community)
  +         AssertEqual(expected.rows, nrow(chains))
  +         CheckChains(community, chains)
  + 
  +         chains <- ThreeNodeChains(community, exclude.loops=TRUE)
  +         AssertEqual(expected.rows.no.loops, nrow(chains))
  +         CheckChains(community, chains)
  +     }
  + }
  > 
  > TestTrophicHeight <- function()
  + {
  +     AssertEqual(c(S=NA), TrophicHeight(c1, include.isolated=TRUE))
  +     AssertEqual(c(S=NA), TrophicHeight(c1, include.isolated=FALSE))
  +     AssertEqual(c(S=NA), TrophicHeight(c2, include.isolated=TRUE))
  +     AssertEqual(c(S=NA), TrophicHeight(c2, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2), TrophicHeight(c3, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2), TrophicHeight(c3, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,P=3), TrophicHeight(c4, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2,P=3), TrophicHeight(c4, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,O=2.5), TrophicHeight(c5, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2,O=2.5), TrophicHeight(c5, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,P=3), TrophicHeight(c6, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2,P=3), TrophicHeight(c6, include.isolated=FALSE))
  +     AssertEqual(c(A=1,B=2,C=3,D=1,E=1), TrophicHeight(c7, include.isolated=TRUE))
  +     AssertEqual(c(A=1,B=2,C=3,D=NA,E=NA), 
  +                 TrophicHeight(c7, include.isolated=FALSE))
  + 
  +     # Lower tolerance required for Mac Pro in GIS lab.
  +     AssertEqual(c(rep(1,31),2,2,2,2,10/3,2,2.41860465116279055309,2,2,
  +                   2,2,2,2,2,2,4.2,2,2,2,2,10/3,
  +                   4.60252672497570447518, 5.16833667334669311089, 
  +                   5.16833667334669311089, 5.83500334001336007361), 
  +                 unname(TrophicHeight(TL84)), 
  +                 tolerance=1e-6)
  +     AssertEqual(c(1,1,NA,1,1,1,1,NA,1,1,1,NA,rep(1,13),NA,1,NA,NA,1,1,
  +                   2,2,2,2,10/3,2,2.41860465116279055309,2,2,
  +                   2,2,2,2,2,2,4.2,2,2,2,2,10/3,
  +                   4.60252672497570447518, 5.16833667334669311089, 
  +                   5.16833667334669311089, 5.83500334001336007361), 
  +                 unname(TrophicHeight(TL84, include.isolated=FALSE)), 
  +                 tolerance=1e-6)
  + }
  > 
  > TestTrophicLevel <- function()
  + {
  +     AssertEqual(c(S=NA), PreyAveragedTrophicLevel(c1))
  +     AssertEqual(c(S=NA), PreyAveragedTrophicLevel(c2))
  +     AssertEqual(c(R=1,C=2), PreyAveragedTrophicLevel(c3))
  +     AssertEqual(c(R=1,C=2,P=3), PreyAveragedTrophicLevel(c4))
  +     AssertEqual(c(R=1,C=2,O=2.5), PreyAveragedTrophicLevel(c5))
  +     AssertEqual(c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  +                           1,1,1,1,1,1,1,2,2,2,2,3.14285714285714,2,
  +                           2.10714285714286,2,2,2,2,2,2,2,2,3.20535714285714,
  +                           2,2,2,2,3.14285714285714,3.17134353741497,
  +                           3.52995086923658,3.52995086923658,
  +                           3.80267814196386), 
  +                 unname(PreyAveragedTrophicLevel(TL84)))
  + 
  +     AssertEqual(c(S=NA), PreyAveragedTrophicLevel(c1, include.isolated=FALSE))
  +     AssertEqual(c(S=NA), PreyAveragedTrophicLevel(c2, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2), PreyAveragedTrophicLevel(c3, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,P=3), PreyAveragedTrophicLevel(c4, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,O=2.5), PreyAveragedTrophicLevel(c5, include.isolated=FALSE))
  + 
  +     # c7 is not energetically feasible so all trophic levels are NA
  +     AssertEqual(c(A=NA,B=NA,C=NA,D=NA,E=NA), 
  +                 PreyAveragedTrophicLevel(c7, include.isolated=FALSE))
  +     AssertEqual(c(A=NA,B=NA,C=NA,D=NA,E=NA), 
  +                 PreyAveragedTrophicLevel(c7, include.isolated=TRUE))
  + 
  +     AssertEqual(c(1,1,NA,1,1,1,1,NA,1,1,1,NA,1,1,1,1,1,1,1,1,1,1,1,1,
  +                           1,NA,1,NA,NA,1,1,2,2,2,2,3.14285714285714,2,
  +                           2.10714285714286,2,2,2,2,2,2,2,2,3.20535714285714,
  +                           2,2,2,2,3.14285714285714,3.17134353741497,
  +                           3.52995086923658,3.52995086923658,
  +                           3.80267814196386), 
  +                 unname(PreyAveragedTrophicLevel(TL84, include.isolated=FALSE)))
  + }
  > 
  > TestTrophicSpecies <- function()
  + {
  +     AssertEqual(c(S=NA), TrophicSpecies(c1, include.isolated=FALSE))
  +     AssertEqual(c(S=1), TrophicSpecies(c1, include.isolated=TRUE))
  +     AssertEqual(c(S=NA), TrophicSpecies(c2, include.isolated=FALSE))
  +     AssertEqual(c(S=1), TrophicSpecies(c2, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2), TrophicSpecies(c3, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2), TrophicSpecies(c3, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2,P=3), TrophicSpecies(c4, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,P=3), TrophicSpecies(c4, include.isolated=TRUE))
  +     AssertEqual(c(R=1,C=2,O=3), TrophicSpecies(c5, include.isolated=FALSE))
  +     AssertEqual(c(R=1,C=2,O=3), TrophicSpecies(c5, include.isolated=TRUE))
  + 
  +     # From Jonsson et al 2005 AER. Isolated species assigned NA.
  +     target <- c(1,2,NA,3,4,3,5,NA,6,1,1,NA,4,7,4,8,6,7,2,3,6,7,
  +                 4,6,3,NA,3,NA,NA,6,3,9,9,10,11,12,13,14,15,11,
  +                 15,16,15,9,15,17,18,15,15,15,15,12,19,20,20,21)
  +     AssertEqual(target, unname(TrophicSpecies(TL84, include.isolated=FALSE)))
  + 
  +     # Isolated species included - these are given a trophic level of 1.
  +     target <- c(1,2,3,4,5,4,6,3,7,1,1,3,5,8,5,9,7,8,2,4,7,8,5,7,
  +                 4,3,4,3,3,7,4,10,10,11,12,13,14,15,16,12,16,17,16,
  +                 10,16,18,19,16,16,16,16,13,20,21,21,22)
  +     AssertEqual(target, unname(TrophicSpecies(TL84, include.isolated=TRUE)))
  + }
  > 
  > TestTrophicLinksForNodes <- function()
  + {
  +     AssertEqual(NULL, TrophicLinksForNodes(c1, 'S'))
  +     AssertEqual(data.frame(resource='S', consumer='S', stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c2, 'S'))
  + 
  +     AssertEqual(data.frame(resource='R', consumer='C', stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c3, 'R'))
  +     AssertEqual(data.frame(resource='R', consumer='C', stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c3, 'C'))
  +     AssertEqual(data.frame(resource='R', consumer='C', stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c3, c('R','C')))
  + 
  +     AssertEqual(data.frame(resource='R', consumer='C', stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c4, 'R'))
  +     AssertEqual(data.frame(resource=c('R','C'), consumer=c('C','P'), 
  +                            stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c4, 'C'))
  +     AssertEqual(data.frame(resource='C', consumer='P', stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c4, 'P'))
  +     AssertEqual(data.frame(resource=c('R','C'), consumer=c('C','P'), 
  +                            stringsAsFactors=FALSE), 
  +                 TrophicLinksForNodes(c4, c('R','C','P')))
  + }
  > 
  > TestResolveTrophicLinksToNodeNames <- function()
  + {
  +     f <- cheddar:::.ResolveTrophicLinksToNodeNames
  +     expected = matrix(c('S', 'S'), nrow=1, 
  +                       dimnames=list(NULL, c('resource', 'consumer')))
  +     AssertEqual(expected, f(c1, data.frame(resource='S', consumer='S')))
  +     AssertEqual(expected, f(c1, data.frame(resource=1, consumer='S')))
  +     AssertEqual(expected, f(c1, data.frame(resource=1, consumer=1)))
  +     AssertEqual(expected, f(c1, data.frame(resource='S', consumer=1)))
  +     AssertRaises(f(c3, data.frame(resource='x', consumer='R')))
  +     AssertRaises(f(c3, data.frame(resource='R', consumer='')))
  +     AssertRaises(f(c3, matrix(c(0, 1), ncol=2)))
  +     AssertRaises(f(c3, matrix(c(0, 1), ncol=2)))
  + }
  > 
  > TestResolveTrophicLinksToRowIndices <- function()
  + {
  +     f <- cheddar:::.ResolveTrophicLinksToRowIndices
  +     AssertEqual(NA, f(c1, data.frame(resource='S', consumer='S')))
  +     AssertEqual(NA, f(c1, data.frame(resource=1, consumer=1)))
  +     AssertEqual(1, f(c2, data.frame(resource='S', consumer='S')))
  +     AssertEqual(1, f(c2, data.frame(resource=1, consumer=1)))
  +     AssertEqual(1, f(c3, data.frame(resource='R', consumer='C')))
  +     AssertEqual(NA, f(c3, data.frame(resource='R', consumer='R')))
  +     AssertEqual(NA, f(c3, data.frame(resource='C', consumer='C')))
  +     AssertEqual(NA, f(c3, data.frame(resource='C', consumer='R')))
  +     AssertEqual(c(1,NA,NA,NA), 
  +                 f(c3, data.frame(resource=c('R','R','C','C'), 
  +                                  consumer=c('C','R','C','R'))))
  +     AssertRaises(f(c3, data.frame(resource='x', consumer='R')))
  +     AssertRaises(f(c3, data.frame(resource='R', consumer='')))
  +     AssertRaises(f(c3, matrix(resource=0, consumer=1)))
  +     AssertRaises(f(c3, matrix(resource=1, consumer=0)))
  + }
  > 
  > TestDoLinksExist <- function()
  + {
  +     f <- cheddar:::.DoLinksExist
  +     AssertEqual(FALSE, f(c1, data.frame(resource='S', consumer='S')))
  +     AssertEqual(FALSE, f(c1, data.frame(resource=1, consumer=1)))
  +     AssertEqual(TRUE, f(c2, data.frame(resource='S', consumer='S')))
  +     AssertEqual(TRUE, f(c2, data.frame(resource=1, consumer=1)))
  +     AssertEqual(TRUE, f(c3, data.frame(resource='R', consumer='C')))
  +     AssertEqual(FALSE, f(c3, data.frame(resource='R', consumer='R')))
  +     AssertEqual(FALSE, f(c3, data.frame(resource='C', consumer='C')))
  +     AssertEqual(FALSE, f(c3, data.frame(resource='C', consumer='R')))
  +     AssertEqual(c(TRUE,FALSE,FALSE,FALSE), 
  +                 f(c3, data.frame(resource=c('R','R','C','C'), 
  +                                  consumer=c('C','R','C','R'))))
  + }
  > 
  > TestRemoveCannibalisticLinks <- function()
  + {
  +     AssertEqual(0, NumberOfTrophicLinks(c1))
  +     AssertEqual(0, NumberOfTrophicLinks(RemoveCannibalisticLinks(c1)))
  +     AssertEqual(1, NumberOfTrophicLinks(c2))
  +     AssertEqual(0, NumberOfTrophicLinks(RemoveCannibalisticLinks(c2)))
  +     AssertEqual(1, NumberOfTrophicLinks(RemoveCannibalisticLinks(c3)))
  +     AssertEqual(2, NumberOfTrophicLinks(RemoveCannibalisticLinks(c4)))
  +     AssertEqual(3, NumberOfTrophicLinks(RemoveCannibalisticLinks(c5)))
  +     AssertEqual(2, NumberOfTrophicLinks(RemoveCannibalisticLinks(c7)))
  +     AssertEqual(269, NumberOfTrophicLinks(TL84))
  +     AssertEqual(5, length(Cannibals(TL84)))
  +     AssertEqual(264, NumberOfTrophicLinks(RemoveCannibalisticLinks(TL84)))
  +     AssertEqual(0, length(Cannibals(RemoveCannibalisticLinks(TL84))))
  + }
  > 
  > TestShortestPathLengths <- function()
  + {
  +     # Helper function that creates expected matrices
  +     F <- function(data, nodes)
  +     {
  +         m <- matrix(data, ncol=length(nodes), dimnames=list(nodes, nodes))
  +         mode(m) <- 'numeric' # Necessary for a 1 x 1 matrix that contains only NA
  +         return (m)
  +     }
  + 
  +     AssertEqual(F(0, 'S'), ShortestPaths(c1))
  +     AssertEqual(F(0, 'S'), ShortestPaths(c2))
  +     AssertEqual(F(c(0,1, 1,0), c('R','C')), ShortestPaths(c3))
  +     AssertEqual(F(c(0,1,2, 1,0,1, 2,1,0), c('R','C','P')), ShortestPaths(c4))
  +     AssertEqual(F(c(0,1,1, 1,0,1, 1,1,0), c('R','C','O')), ShortestPaths(c5))
  +     AssertEqual(F(c(0,1,2, 1,0,1, 2,1,0), c('R','C','P')), ShortestPaths(c6))
  + }
  > 
  > TestSumDietGap <- function()
  + {
  +     # Test the C function directly
  +     f <- function(pm, expected)
  +     {
  +         n <- ncol(pm)
  +         sum_diet_gaps <- as.integer(0)
  +         status <- as.integer(-1)
  + 
  +         res <- .C('sum_diet_gaps', 
  +                   as.integer(pm), 
  +                   as.integer(n), 
  +                   as.integer((1:n) - 1),   # 0-indexed
  +                   sum_diet_gaps=sum_diet_gaps, 
  +                   status=status)
  +         AssertEqual(res$sum_diet_gaps, expected)
  +         return (res)
  +     }
  + 
  +     f(matrix(0, ncol=1), 0)
  +     f(matrix(1, ncol=1), 0)
  +     f(matrix(c(0,0,0,0), ncol=2), 0)
  +     f(matrix(c(1,1,1,1), ncol=2), 0)
  +     f(matrix(c(1,0,1,0), ncol=2), 0)
  +     f(matrix(c(0,1,0,1), ncol=2), 0)
  + 
  +     f(matrix(c(1, 1, 0, 
  +                0, 1, 1,
  +                1, 0, 1), ncol=3, byrow=TRUE), 1)
  +     f(matrix(c(1, 1, 0, 
  +                0, 0, 1,
  +                1, 1, 1), ncol=3, byrow=TRUE), 2)
  +     f(matrix(c(1, 1, 1, 
  +                0, 0, 0,
  +                1, 1, 1), ncol=3, byrow=TRUE), 3)
  +     f(matrix(c(1, 1, 1, 
  +                0, 0, 0,
  +                0, 0, 0), ncol=3, byrow=TRUE), 0)
  +     f(matrix(c(1, 1, 1, 
  +                0, 1, 1,
  +                0, 0, 1), ncol=3, byrow=TRUE), 0)
  +     f(matrix(c(0, 0, 1, 
  +                0, 1, 1,
  +                1, 1, 1), ncol=3, byrow=TRUE), 0)
  + 
  +     f(matrix(c(1, 0, 0, 1, 
  +                1, 0, 0, 0,
  +                0, 0, 0, 1,
  +                1, 0, 0, 1), ncol=4, byrow=TRUE), 2)
  + 
  +     f(matrix(c(1, 1, 0, 0, 0, 0, 
  +                1, 1, 1, 1, 0, 0, 
  +                1, 1, 1, 1, 0, 0, 
  +                0, 0, 0, 0, 0, 0, 
  +                1, 1, 1, 1, 0, 0, 
  +                0, 1, 0, 1, 0, 0), ncol=6, byrow=TRUE), 4)
  + 
  +     f(matrix(c(1, 1, 0, 1, 1, 1, 
  +                0, 1, 1, 1, 0, 0, 
  +                0, 1, 1, 1, 1, 1, 
  +                0, 1, 1, 0, 1, 1, 
  +                0, 0, 0, 1, 1, 1, 
  +                1, 1, 1, 1, 0, 1), ncol=6, byrow=TRUE), 9)
  + 
  +     f(matrix(c(0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 1, 0, 1, 
  +                0, 0, 1, 1, 1, 1, 
  +                0, 1, 1, 1, 1, 1, 
  +                1, 1, 1, 1, 1, 1, 
  +                0, 1, 0, 0, 0, 1), ncol=6, byrow=TRUE), 0)
  + 
  +     f(matrix(c(0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 1, 0, 1, 
  +                0, 0, 1, 0, 1, 0, 
  +                0, 1, 1, 0, 0, 0, 
  +                1, 1, 1, 1, 1, 0, 
  +                0, 1, 0, 0, 0, 1), ncol=6, byrow=TRUE), 6)
  + 
  +     f(matrix(c(1, 0, 1, 0, 1, 0, 
  +                0, 1, 0, 1, 0, 1, 
  +                1, 0, 1, 0, 1, 0, 
  +                0, 1, 0, 1, 0, 1, 
  +                1, 0, 1, 0, 1, 0, 
  +                0, 1, 0, 1, 0, 1), ncol=6, byrow=TRUE), 12)
  + 
  +     f(matrix(c(0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 0, 0, 0, 
  +                0, 0, 0, 0, 0, 1), ncol=6, byrow=TRUE), 0)
  + 
  +     f(PredationMatrix(TL84), 424)
  + 
  +     # Test the R function
  +     AssertEqual(SumDietGaps(TL84), 424)
  + }
  > 
  > TestMinimiseSumDietGaps <- function()
  + {
  +     # Can't test for exact values because simulated annealing learning is 
  +     # stochastic and not guaranteed to reach a global minimum
  +     to.test <- list(list(c2, 0), 
  +                     list(c3, 0),
  +                     list(c4, 0),
  +                     list(c5, 0),
  +                     list(c6, 0),
  +                     list(TL84, 10), 
  +                     list(TL86, 10), 
  +                     list(YthanEstuary, 277),
  +                     list(SkipwithPond, 31),
  +                     list(BroadstoneStream, 7),
  +                     list(Benguela, 27))
  +     for(index in 1:length(to.test))
  +     {
  +         community <- to.test[[index]][[1]]
  +         expected <- to.test[[index]][[2]]
  +         print(community)
  + 
  +         res <- MinimiseSumDietGaps(community, T.start=1, T.stop=0.1, c=0.99, 
  +                                    swaps.per.T=1000, n=3)
  + 
  +         if(0==expected)
  +         {
  +             AssertEqual(0, res$sum.gaps)
  +         }
  +         else
  +         {
  +             if( (res$sum.gaps / expected) > 3)
  +             {
  +                 stop(paste('Best diet gap for', community, 'of', res$sum.gaps,
  +                            'is much higher than the expected value of', 
  +                             expected))
  +             }
  +         }
  +     }
  + }
  > 
  > TestTrophicSimilarity <- function()
  + {
  +     # Helper function that creates expected matrices
  +     F <- function(data, nodes)
  +     {
  +         m <- matrix(data, ncol=length(nodes), dimnames=list(nodes, nodes))
  +         mode(m) <- 'numeric' # Necessary for a 1 x 1 matrix that contains only NA
  +         return (m)
  +     }
  +     AssertEqual(F(NA, 'S'), TrophicSimilarity(c1))
  +     AssertEqual(F(NA, 'S'), TrophicSimilarity(c2))
  +     AssertEqual(F(c(1,0,0,1), c('R','C')), TrophicSimilarity(c3))
  +     AssertEqual(F(c(1,0,1,0,1,0,1,0,1), c('R','C','P')), TrophicSimilarity(c4))
  +     AssertEqual(F(c(1,1/3,1/3,1/3,1,1/3,1/3,1/3,1), c('R','C','O')), 
  +                 TrophicSimilarity(c5))
  +     AssertEqual(F(c(1,0,1,0,1,0,1,0,1), c('R','C','P')), TrophicSimilarity(c6))
  +     AssertEqual(F(c(1,1/3,1/3,0,0, 1/3,1,1/3,0,0, 1/3,1/3,1,0,0, 0,0,0,NA,NA, 0,0,0,NA,NA), 
  +                   LETTERS[1:5]), TrophicSimilarity(c7))
  + }
  > 
  > TestOmnivores <- function()
  + {
  +     AssertEqual(vector(mode='character'), Omnivores(c1))
  +     AssertEqual(vector(mode='character'), Omnivores(c2))
  +     AssertEqual(vector(mode='character'), Omnivores(c3))
  +     AssertEqual(vector(mode='character'), Omnivores(c4))
  +     AssertEqual('O', Omnivores(c5))
  +     AssertEqual(vector(mode='character'), Omnivores(c6))
  +     AssertEqual(vector(mode='character'), Omnivores(c7))
  + 
  +     AssertEqual(c('Microzooplankton', 'Zooplankton', 'Ctenophores', 
  +         'Chrysaora quinquecirrha', 'Other suspension feeders', 'Mya', 
  +         'Crassostrea virginica', 'Callinectes sapidus', 'Anchoa mitchilli', 
  +         'Brevoortia tyrannus', 'Trinectes maculatus', 'Leiostomus xanthurus', 
  +         'Morone americana', 'Pomatomus saltatrix', 'Paralichthys dentatus', 
  +         'Morone saxatilis'), Omnivores(ChesapeakeBay))
  +     AssertEqual(c('Microzooplankton', 'Zooplankton', 'Ctenophores', 
  +         'Chrysaora quinquecirrha', 'Other suspension feeders', 'Mya', 
  +         'Crassostrea virginica', 'Callinectes sapidus', 'Anchoa mitchilli', 
  +         'Brevoortia tyrannus', 'Trinectes maculatus', 'Leiostomus xanthurus', 
  +         'Pomatomus saltatrix', 'Paralichthys dentatus', 'Morone saxatilis'), 
  +       Omnivores(ChesapeakeBay, level=ChainAveragedTrophicLevel))
  + }
  > 
  > TestOmnivory <- function()
  + {
  +     AssertEqual(0, Omnivory(c1))
  +     AssertEqual(0, Omnivory(c2))
  +     AssertEqual(0, Omnivory(c3))
  +     AssertEqual(0, Omnivory(c4))
  +     AssertEqual(1/3, Omnivory(c5))
  +     AssertEqual(0, Omnivory(c6))
  +     AssertEqual(0, Omnivory(c7))
  +     # Value of 0.455 for Chesapeake Bay presented by Bersier et al 2002 Ecology
  +     res <- Omnivory(ChesapeakeBay, level=ChainAveragedTrophicLevel)
  +     AssertEqual(0.455, round(res, 3))
  + }
  > 
  > TestNodeQuantitativeDescriptors <- function()
  + {
  +     res <- NodeQuantitativeDescriptors(ChesapeakeBay, 'biomass.flow')
  + 
  +     # The values in Bersier et al 2002, Table 1:
  +     expected <- matrix(c(
  + 0, 7,      0, 80051, 0,    3.19, 0,    0,    0,    0,    0,    0,    2.62, 5.47,
  + 0, 8,      0,  2977, 0,    3.21, 0,    0,    0,    0,    0,    0,    2.64, 0.21,
  + 0, 6,      0,294955, 0,    3.63, 0,    0,    0,    0,    0,    0,    2.99,22.96,
  + 0, 1,      0, 18086, 0,    1,    0,    0,    0,    0,    0,    0,    0.82, 0.39,
  + 0, 1,      0, 88721, 0,    1,    0,    0,    0,    0,    0,    0,    0.82, 1.9,
  + 1, 1,  88721, 31638, 1,    1,    0.5,  0.74, 0,    0,    0.65, 3.9,  0.82, 0.68,
  + 3, 5,  64224, 11742, 2.13, 2.42, 0.47, 0.83, 0.89, 1,    1.39, 6,    2,    0.61,
  + 3, 7,  46389,  9855, 1.81, 2.48, 0.42, 0.77, 0.89, 0.56, 1.19, 3.69, 2.04, 0.52,
  + 3, 1,  10447,   552, 2.01, 1,    0.67, 0.97, 2,    1.01, 1.31, 0.92, 0.82, 0.01,
  + 2, 0,   1711,     0, 1.88, 0,    1,    1,    1,    0.88, 1.23, 0.14, 0,    0,
  + 3, 1,   4594,   538, 1.41, 1,    0.58, 0.92, 0.89, 0.27, 0.92, 0.28, 0.82, 0.01,
  + 3, 2,   2488,   224, 1.41, 1.18, 0.54, 0.93, 0.89, 0.26, 0.92, 0.15, 0.97, 0.01,
  + 3, 0,   4830,     0, 1.41, 0,    1,    1,    0.89, 0.26, 0.92, 0.3,  0,    0,
  + 1, 5, 160831,   609, 1,    3.41, 0.23, 0.99, 0,    0,    0.65, 7.06, 2.8,  0.04,
  + 1, 6,  25062,   547, 1,    2.94, 0.25, 0.94, 0,    0,    0.65, 1.1,  2.42, 0.03,
  + 1, 2,  57335,  4593, 1,    1.07, 0.48, 0.92, 0,    0,    0.65, 2.52, 0.88, 0.11,
  + 2, 0,  54048,     0, 1.89, 0,    1,    1,    0,    0,    1.24, 4.49, 0,    0,
  + 1, 6,  14075,  1027, 1,    1.31, 0.43, 0.91, 0,    0,    0.65, 0.62, 1.08, 0.03,
  + 7, 2,   8593,   295, 4.12, 1.05, 0.8,  0.99, 2.59, 1.48, 2.69, 1.55, 0.86, 0.03,
  + 1, 0,      5,     0, 1,    0,    1,    1,    0,    0,    0.65, 0,    0,    0,
  + 1, 1,     26,     0, 1,   1,    0.5,  0.99, 0,    0,    0.65, 0,    0.82, 0,
  + 3, 6,   1823,   153, 1.59, 3.58, 0.31, 0.84, 0.89, 0.55, 1.04, 0.13, 2.94, 0.1,
  + 3, 3,    273,    21, 1.42, 2.64, 0.35, 0.87, 0.89, 0.36, 0.93, 0.02, 2.17, 0,
  + 1, 0,      5,     0, 1,    0,    1,    1,    0,    0,    0.65, 0,    0,    0,
  + 3, 0,     10,     0, 1.93, 0,    1,    1,    0,    0,    1.26, 0,    0,    0,
  + 4, 0,     96,     0, 2.95, 0,    1,    1,    0.75, 0.36, 1.93, 0.01, 0,    0,
  + 5, 1,    483,    10, 2.66, 1,    0.72, 0.99, 0.65, 0.14, 1.74, 0.06, 0.82, 0,
  + 3, 0,    150,     0, 2.56, 0,    1,    1,    0.89, 0.38, 1.67, 0.02, 0,    0,
  + 3, 0,    219,     0, 2.24, 0,    1,    1,    0,    0,    1.46, 0.02, 0,    0,
  + 3, 0,     16,     0, 2.41, 0,    1,    1,    0.89, 0.90, 1.58, 0,    0,    0,
  + 1, 1,     91,     4, 1,    1,    0.5,  0.96, 0,    0,    0.65, 0,    0.82, 0,
  + 4, 0,     26,     0, 3.11, 0,    1,    1,    1.83, 0.82, 2.03, 0,    0,    0,
  + 4, 0,     30,     0, 2.52, 0,    1,    1,    0,    0, 1.65, 0,       0,    0
  + ), ncol=14, byrow=TRUE)
  +     colnames(expected) <- colnames(res)
  +     rownames(expected) <- rownames(res)
  + 
  +     # Some differences to the published values
  +     # TODO Contact Bersier to get to the bottom of these differences
  +     expected['Ctenophores','bIn'] <- 10446          # Change from 10447
  +     expected['Macoma spp','bIn'] <- 57334           # Change from 57335
  +     expected['Leiostomus xanthurus','bIn'] <- 482   # Change from 483
  +     expected['Arius felis','bIn'] <- 218            # Change from 219
  +     expected['Microzooplankton','nP'] <- 2.43       # Change from 2.42
  +     expected['Leiostomus xanthurus','d.prime'] <- 0.73 # Change from 0.72
  +     expected['Callinectes sapidus','v'] <- 0.01     # Change from 0.03
  +     expected['Anchoa mitchilli','v'] <- 0.01        # Change from 0.1
  + 
  +     # bIn and bOut are rounded to zero dp in the paper
  +     res[,'bIn'] <- round(res[,'bIn'], 0)
  +     res[,'bOut'] <- round(res[,'bOut'], 0)
  +     AssertEqual(round(res, 2), expected)
  + }
  > 
  > TestQuantitativeDescriptors <- function()
  + {
  +     res <- QuantitativeDescriptors(ChesapeakeBay, 'biomass.flow')
  +     expected <- matrix(c(
  +         0.364,   0.364,   0.455,
  +         0.485,   0.485,   0.394,
  +         0.152,   0.152,   0.152,
  +         0.75,    0.711,   0.317,    # Col 3 shown as 0.316 in the paper
  +         2.212,   1.372,   2.096,
  +         0.067,   0.042,   0.064,
  +         0.397,   0.451,   0.011,
  +         0.055,   0.055,   0.195,
  +         0.288,   0.287,   0.112,
  +         0.260,   0.207,   0.682,
  +         3.157,   1.605,   1.517,
  +         3.000,   1.618,   0.675,
  +         1.096,   0.488,   1.910,
  +         6.000,   2.970,   6.408,
  +         0.455,   0.510,   0.280, 
  +         2.607,   1.801,   1.375,
  +         3.476,   1.911,   2.818,    # Col 3 shown as 2.812 in the paper
  +         0.739,   0.645,   1.882,
  +         1.195,   1.032,   4.066
  +         ), ncol=3, byrow=TRUE)
  +     colnames(expected) <- colnames(res)
  +     rownames(expected) <- rownames(res)
  +     AssertEqual(round(res, 3), expected)
  + }
  > 
  > proc.time()
     user  system elapsed 
     0.39    0.07    0.40 
Running the tests in 'tests/run.R' failed.
Complete output:
  > # Runs all of cheddar's tests. You must cd cheddar/tests before running 
  > # Rscript run_all.R
  > library(cheddar)
  > 
  > # Data for test plans
  > data(Benguela, BroadstoneStream, ChesapeakeBay, SkipwithPond, TL84, TL86, 
  +      YthanEstuary, pHWebs, Millstream)
  > 
  > # One species. No properties. No trophic links.
  > c1 <- Community(nodes=data.frame(node='S'), properties=list(title='c1'))
  > 
  > # One cannibalistic species
  > c2 <- Community(nodes=data.frame(node='S'), 
  +                 trophic.links=cbind(resource='S', consumer='S'), 
  +                 properties=list(title='c2'))
  > 
  > # Resource-consummer
  > c3 <- Community(nodes=data.frame(node=c('R','C')), 
  +                 trophic.links=cbind(resource='R', consumer='C'), 
  +                 properties=list(title='c3'))
  > 
  > # Three-species chain
  > c4 <- Community(nodes=data.frame(node=c('R','C','P')), 
  +                 trophic.links=cbind(resource=c('R','C'), 
  +                                     consumer=c('C','P')), 
  +                 properties=list(title='c4'))
  > 
  > # IGP
  > c5 <- Community(nodes=data.frame(node=c('R','C','O')), 
  +                 trophic.links=cbind(resource=c('R','R','C'), 
  +                                     consumer=c('C','O','O')), 
  +                 properties=list(title='c5'))
  > 
  > # Three species chain with M, N, taxonomy and trophic link properties
  > c6 <- Community(nodes=data.frame(node=c('R','C','P'), 
  +                                  M=c(1.5, 5, 100), 
  +                                  N=c(1000, 10, 5.5), 
  +                                  order=c('Order 1', 'Order 2', 'Order 2'), 
  +                                  family=c('Family 1', 'Family 2', 'Family 3'), 
  +                                  stringsAsFactors=FALSE), 
  +                 trophic.links=data.frame(resource=c('R','C'), 
  +                                          consumer=c('C','P'),  
  +                                          link.evidence=c('Inferred', 'Known'), 
  +                                          link.strength=c(0.5, 0.2), 
  +                                          stringsAsFactors=FALSE), 
  +                 properties=list(title='c6', M.units='g', 
  +                                 N.units='m^-3'))
  > 
  > # A community with three nodes:
  > #   A is a cannibal with no resources other than itself
  > #   B consumes A
  > #   C is a cannibal that consumes B
  > #   D is a cannibal and has no other resources or consumers
  > #   E has no resources or consumers
  > # This community is biologically silly but mathematically interesting for 
  > # testing node status: basal, intermediate, top-level etc
  > c7 <- Community(properties=list(title='Test'),
  +                 nodes=data.frame(node=c('A', 'B', 'C', 'D', 'E')), 
  +                 trophic.links=data.frame(resource=c('A', 'A', 'B', 'C', 'D'), 
  +                                          consumer=c('A', 'B', 'C', 'C', 'D')))
  > 
  > # 10 species with different categories
  > c8 <- Community(nodes=data.frame(node=paste('Species', 1:8), 
  +                                  M=c(10,  9,  5, 0.1, 0.2, 0.3, 1, 2),
  +                                  N=c(10, 1,  21, 900, 500, 100, 1, 5),
  +                                  category=c(rep('vert.endo', 3), 
  +                                             rep('', 3),
  +                                             rep('vert.ecto', 2))),
  +                 properties=list(title='c7', M.units='g', N.units='m^-3'))
  > 
  > AssertEqual <- function(a, b, ...)
  + {
  +     res <- all.equal(a, b, ...)
  +     if(!isTRUE(res))
  +     {
  +         stop(paste(res, collapse="\n"))
  +     }
  + }
  > 
  > AssertTrue <- function(v)
  + {
  +     AssertEqual(TRUE, v)
  + }
  > 
  > AssertFalse <- function(v)
  + {
  +     AssertEqual(FALSE, v)
  + }
  > 
  > AssertNull <- function(v)
  + {
  +     AssertEqual(NULL, v)
  + }
  > 
  > AssertRaises <- function(ex)
  + {
  +     # A function that expects an exception to be raise when ex is evalutated
  +     res <- tryCatch(eval(ex), error=function(e) e)
  +     if(!"error" %in% class(res))
  +     {
  +         stop('Did not raise error\n')
  +     }
  + }
  > 
  > RunTests <- function(tests)
  + {
  +     # tests should be a vector of function names
  +     options(error=function()
  +             {
  +                 traceback(3)
  +                 stop()
  +             }, 
  +             stringsAsFactors=FALSE)
  + 
  +     if(0==length(tests))
  +     {
  +         stop('No tests to run! Is the working directory cheddar/tests ?')
  +     }
  +     else
  +     {
  +         for(test in tests)
  +         {
  +             cat(paste('Running [', test, ']\n', sep=''))
  +             do.call(test, args=list())
  +        }
  +     }
  + }
  > 
  > # Source all files in this dir except this one
  > files <- list.files(getwd(), pattern='*R$')
  > files <- setdiff(files, 'run.R')
  > junk <- sapply(file.path(getwd(), files), source)
  > tests <- commandArgs(trailingOnly=TRUE)
  > if(0==length(tests))
  + {
  +     tests <- ls(pattern=glob2rx('^Test*'))
  + }
  > 
  > RunTests(tests)
  Running [TestAggregateCommunitiesBy]
  Running [TestAggregateCommunitiesFailures]
  Running [TestAggregateCommunitiesProperties]
  Running [TestAggregateCommunitiesSingle]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Skipwith Pond containing 37 nodes and 381 trophic links 
  Running [TestAggregateCommunityMeans]
  Running [TestBasalNodes]
  Running [TestBodyMassBins]
  Running [TestCannibals]
  Running [TestCommunityBasic]
  Running [TestCommunityCollectionFailures]
  Running [TestCommunityCollectionProperties]
  Running [TestCommunityCollectionSingle]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Skipwith Pond containing 37 nodes and 381 trophic links 
  Running [TestCommunityNPS]
  Running [TestCommunityProperties]
  Running [TestCommunityPropertyNames]
  Running [TestCommunityTrophicLinks]
  Running [TestConnectedNodes]
  Running [TestConsumersByNode]
  Running [TestConsumersOfNodes]
  Running [TestDegree]
  Running [TestDegreeDistribution]
  Running [TestDirectedConnectance]
  Running [TestDoLinksExist]
  Running [TestFractionBasalNodes]
  Running [TestFractionConnectedNodes]
  Running [TestFractionIntermediateNodes]
  Running [TestFractionIsolatedNodes]
  Running [TestFractionNonBasalNodes]
  Running [TestFractionNonTopLevelNodes]
  Running [TestFractionOfNodesByClass]
  Running [TestFractionTopLevelNodes]
  Running [TestFractions]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Test containing 5 nodes and 5 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Running [TestInDegree]
  Running [TestIntermediateNodes]
  Running [TestIsolatedNodes]
  Running [TestLinkageDensity]
  Running [TestLumpNodes]
  Running [TestLumpTrophicSpecies]
  Running [TestMinimiseSumDietGaps]
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Ythan Estuary containing 92 nodes and 417 trophic links 
  Skipwith Pond containing 37 nodes and 381 trophic links 
  Broadstone Stream containing 37 nodes and 132 trophic links 
  Benguela containing 29 nodes and 203 trophic links 
  Running [TestNPS]
  Running [TestNodeNameIndices]
  Running [TestNodePropertyNames]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  Running [TestNodeQuantitativeDescriptors]
  Running [TestNodesWithoutMOrN]
  Running [TestNonBasalNodes]
  Running [TestNonTopLevelNodes]
  Running [TestNormalisedTrophicGenerality]
  Running [TestNormalisedTrophicVulnerability]
  Running [TestNumberOfNodes]
  Running [TestNumberOfNodesByClass]
  Running [TestNumberOfTrophicLinks]
  Running [TestNvMConvexHull]
  Running [TestNvMLinearRegressions]
  Running [TestNvMSlopeAndIntercept]
  Running [TestNvMSlopeAndInterceptByClass]
  Running [TestNvMTriTrophic1]
  Running [TestNvMTriTrophic2]
  Running [TestNvMTriTrophic3]
  Running [TestOmnivores]
  Running [TestOmnivory]
  Running [TestOrderCommunity]
  Running [TestOutDegree]
  Running [TestPersistCollection]
  A collection of 10 communities
  A collection of 2 communities
  Running [TestPersistCommunity]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Ythan Estuary containing 92 nodes and 417 trophic links 
  Skipwith Pond containing 37 nodes and 381 trophic links 
  Broadstone Stream containing 37 nodes and 132 trophic links 
  Benguela containing 29 nodes and 203 trophic links 
  Running [TestPlotWagonWheel]
  [1] "D:\\temp\\RtmpKwfnjI\\file28e741e823fe1"
  Running [TestPredationMatrix]
  Running [TestPredationMatrixToLinks]
  Running [TestQuantitativeDescriptors]
  Running [TestRemoveCannibalisticLinks]
  Running [TestRemoveIsolatedNodes]
  Running [TestRemoveNodes]
  Running [TestResolveToNodeIndices]
  Running [TestResolveTrophicLinksToNodeNames]
  Running [TestResolveTrophicLinksToRowIndices]
  Running [TestResourceLargerThanConsumer]
  Running [TestResourcesAndConsumersByNode]
  Running [TestResourcesByNode]
  Running [TestResourcesOfNodes]
  Running [TestShortestPathLengths]
  Running [TestSimplePlotFunctions]
  PlotAuppervAlower 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7475d24d84"
  PlotBCvBR 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7442ce7300"
  PlotBDistribution 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7462a841ab"
  PlotBPyramid 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e744e9e4e03"
  PlotBRvBC 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7430882c88"
  PlotBSpectrum 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e743ccd7264"
  PlotBvM 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e744db4074"
  PlotBvRankB 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e744e9f536a"
  PlotCircularWeb 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7420952a1c"
  PlotDegreeDistribution 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e746f5f1b43"
  PlotMCvMR 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e741023e32"
  PlotMDistribution 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e747b466652"
  PlotMRvMC 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e747dc32f62"
  PlotMvB 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e746d9f48ca"
  PlotMvN 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e748146088"
  PlotMvRankM 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e743a29527c"
  PlotNCvNR 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e746f502720"
  PlotNDistribution 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7455bd4ed"
  PlotNPyramid 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e744eb611fd"
  PlotNRvNC 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7432306fac"
  PlotNSpectrum 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7486d83f"
  PlotNvM 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e74317b66e2"
  PlotNvRankN 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7471c6547f"
  PlotPredationMatrix 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e74541982b"
  PlotWebByLevel 
  [1] "D:\\temp\\RtmpKwfnjI\\file28e7414c2704c"
  Running [TestSiteBySpeciesMatrix]
  Running [TestStripWhiteSpace]
  Running [TestSumBiomassByClass]
  Running [TestSumDietGap]
  Running [TestSumNByClass]
  Running [TestTLPS]
  Running [TestThreeNodeChains]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Test containing 5 nodes and 5 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Ythan Estuary containing 92 nodes and 417 trophic links 
  Skipwith Pond containing 37 nodes and 381 trophic links 
  Running [TestTopLevelNodes]
  Running [TestTrophicChains]
  c1 containing 1 nodes 
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  c6 containing 3 nodes and 2 trophic links 
  Test containing 5 nodes and 5 trophic links 
  test1 containing 3 nodes and 3 trophic links 
  test2 containing 3 nodes and 4 trophic links 
  test2 containing 3 nodes and 3 trophic links 
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Ythan Estuary containing 92 nodes and 417 trophic links 
  Broadstone Stream containing 37 nodes and 132 trophic links 
  Running [TestTrophicChainsStats]
  Tuesday Lake sampled in 1984 containing 56 nodes and 269 trophic links 
  Tuesday Lake sampled in 1986 containing 57 nodes and 241 trophic links 
  Ythan Estuary containing 92 nodes and 417 trophic links 
  Skipwith Pond containing 37 nodes and 381 trophic links 
  Broadstone Stream containing 37 nodes and 132 trophic links 
  Running [TestTrophicChainsStatsOverflow]
  Unexpected error in trophic_chains_size [Too many chains to count without overflow]
  Running [TestTrophicHeight]
  Running [TestTrophicLevel]
  Running [TestTrophicLinkPropertyNames]
  c2 containing 1 nodes and 1 trophic links 
  c3 containing 2 nodes and 1 trophic links 
  c4 containing 3 nodes and 2 trophic links 
  c5 containing 3 nodes and 3 trophic links 
  Running [TestTrophicLinksForNodes]
  Running [TestTrophicSimilarity]
  Running [TestTrophicSpecies]
  > 
  > proc.time()
     user  system elapsed 
    24.73    0.85   25.82