Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add network methods #235

Merged
merged 41 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
88e6fc7
handle isolated nodes
asizemore Nov 2, 2023
ecf1ddf
Merge branch 'feature-229-add-network' into feature-232-network-methods
asizemore Nov 3, 2023
553bce2
Merge branch 'feature-229-add-network' into feature-232-network-methods
d-callan Jan 22, 2024
547cb52
clean up
d-callan Jan 22, 2024
ce4e2d3
get tests passing again
d-callan Jan 22, 2024
e645293
draft methods to find and remove dup links
d-callan Jan 22, 2024
2157e80
add some more documentation
d-callan Jan 22, 2024
d24fd65
test removing dup links
d-callan Jan 22, 2024
e27a247
add link thresholding draft methods
d-callan Jan 22, 2024
951d473
more helpers for pruning links by weight
d-callan Jan 22, 2024
6e395fd
update documentation
d-callan Jan 22, 2024
f0475ff
test for pruning links by weight
d-callan Jan 22, 2024
36c1206
draft some toJSON Network stuff
d-callan Jan 22, 2024
f492e74
bug preventing toJSON methods loading
d-callan Jan 22, 2024
c5c7c9c
draft some toJSON stuff for Nodes and Links
d-callan Jan 22, 2024
eba2c7a
update documentation
d-callan Jan 22, 2024
7e731d9
a test for writing networks to json
d-callan Jan 22, 2024
81c5897
add config to Network toJSON
d-callan Jan 23, 2024
4dbf616
draft some constructors
d-callan Jan 23, 2024
5c99181
some cleanup and get existing tests passing again
d-callan Jan 23, 2024
ec49615
add test for generating Network from edgeList data.frame and get it p…
d-callan Jan 23, 2024
8b8143d
constructor and classes for kpartite networks from edgeLists
d-callan Jan 23, 2024
8932a0c
typo
d-callan Jan 23, 2024
2eaf3f6
clean up and get tests passing
d-callan Jan 25, 2024
93474de
clean up NodeIdList constructor
d-callan Jan 25, 2024
f159c62
add toJSON methods and tests for KPartiteNetwork
d-callan Jan 25, 2024
9b3b26e
update LinkList constructor to respect weights and colors from edgeLi…
d-callan Jan 25, 2024
0100e51
update description
d-callan Jan 25, 2024
831c2f2
Merge branch 'feature-229-add-network' into feature-232-network-methods
d-callan Jan 26, 2024
aab8a5d
clean up
d-callan Jan 26, 2024
7b68540
Merge branch 'main' into feature-232-network-methods
d-callan Jan 30, 2024
cab623e
wip: review feedback
d-callan Jan 30, 2024
e583411
move partitions class to own file
d-callan Jan 30, 2024
c3d4f6d
typo
d-callan Jan 30, 2024
882dd0a
update collation
d-callan Jan 30, 2024
f296876
get tests passing again
d-callan Jan 30, 2024
ae844fb
fix another case of poor use of isValidEdgeList
d-callan Jan 30, 2024
72f7996
require kpartite networks have at min 2 partitions
d-callan Jan 30, 2024
7d3caec
update kpartitenetwork toJSON to match new data service api
d-callan Jan 30, 2024
06ffea1
get toJSON tests passing again
d-callan Jan 30, 2024
4c6f1dd
improve naming of helper fxn
d-callan Jan 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ Depends:
Collate:
'bin.R'
'class-ContingencyTable.R'
'utils.R'
'class-Node.R'
'constructors-Node.R'
'class-Link.R'
'class-Network.R'
'methods-Links.R'
'methods-Nodes.R'
'methods-KPartiteNetwork.R'
'class-Partitions.R'
'class-KPartiteNetwork.R'
'class-plotdata-bar.R'
'class-plotdata-beeswarm.R'
Expand All @@ -62,11 +64,11 @@ Collate:
'class-plotdata.R'
'group.R'
'methods-ContingencyTable.R'
'methods-network.R'
'methods-KPartiteNetwork.R'
'methods-Network.R'
'panel.R'
'plot.data-package.R'
'utils-bin.R'
'utils-json.R'
'utils-pipe.R'
'utils-stats.R'
'utils.R'
13 changes: 13 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export(findBinSliderValues)
export(findBinWidth)
export(findViewport)
export(fishersTest)
export(getDuplicateLinks)
export(getIsolatedNodes)
export(getQuadrantValues)
export(heatmap)
export(heatmap.dt)
Expand All @@ -62,6 +64,11 @@ export(orderByReferenceValues)
export(outliers)
export(posPredictiveValue)
export(prevalence)
export(pruneDuplicateLinks)
export(pruneIsolatedNodes)
export(pruneLinksAboveWeight)
export(pruneLinksBelowWeight)
export(pruneLinksByPredicate)
export(relativeRisk)
export(scattergl)
export(scattergl.dt)
Expand All @@ -83,16 +90,22 @@ exportClasses(TwoByTwoTable)
exportMethods(allStats)
exportMethods(chiSqResults)
exportMethods(fishersTest)
exportMethods(getDuplicateLinks)
exportMethods(getIsolatedNodes)
exportMethods(getQuadrantValues)
exportMethods(makeVariableDetails)
exportMethods(negPredictiveValue)
exportMethods(oddsRatio)
exportMethods(orderByReferenceValues)
exportMethods(posPredictiveValue)
exportMethods(prevalence)
exportMethods(pruneDuplicateLinks)
exportMethods(pruneIsolatedNodes)
exportMethods(pruneLinksByPredicate)
exportMethods(relativeRisk)
exportMethods(sensitivity)
exportMethods(specificity)
exportMethods(toJSON)
import(data.table)
import(veupathUtils)
importFrom(S4Vectors,SimpleList)
Expand Down
177 changes: 114 additions & 63 deletions R/class-KPartiteNetwork.R
Original file line number Diff line number Diff line change
@@ -1,82 +1,51 @@
#' @include methods-KPartiteNetwork.R
check_partitions <- function(object) {
errors <- character()

if (!!length(getAllNodeIds(object))) {
# Ensure that no node is in multiple partitions
if (length(getAllNodeIds(object)) > data.table::uniqueN(getAllNodeIds(object))) {
errors <- c(errors, 'Found a node in multiple partitions. Nodes can only exist in one partition.')
isLinkWithinPartition <- function(link, partitions) {
if (!inherits(link, "Link")) {
d-callan marked this conversation as resolved.
Show resolved Hide resolved
stop('link must be a Link object')
}
}

return(if (length(errors) == 0) TRUE else errors)
}

#' Partitions
#'
#' A class for representing partitions in a k-partite network
#'
#' @name Partitions-class
#' @rdname Partitions-class
#' @export
setClass("Partitions",
contains = "SimpleList",
prototype = prototype(
elementType = "NodeIdList"
),
validity = check_partitions
)

#' Create a Partition
#'
#' An alias to NodeIdList
#'
#' @name Partition-class
#' @rdname Partition-class
#' @export
Partition <- NodeIdList

#' Create Partitions
#'
#' A list of Partition objects, each containing a list of node
#' ids that belong to a single partition
#'
#' @param partitions list of Partition (or NodeIdList) objects
#' @export
#' @rdname Partitions
Partitions <- function(partitions = list()) {
if (length(partitions) == 0) {
return(new("Partitions", S4Vectors:::SimpleList(list())))
}
if (!inherits(partitions, "Partitions")) {
stop('partitions must be a Partitions object')
}

source <- source(link)
target <- target(link)

if (length(partitions) == 1 && !is.list(partitions)) {
## an edge case i suppose where we had a single partition w a single node
partitions <- list(Partition(partitions))
}
if (is.null(source) || is.null(target)) {
return(FALSE)
}

if (!is.list(partitions)) {
stop('Partitions must be a list')
}
internalLink <- FALSE
if (getPartitionIndex(partitions, source) == getPartitionIndex(partitions, target)) {
internalLink <- TRUE
}

if (!all(unlist(lapply(partitions, inherits, "NodeIdList")))) {
stop('Partitions must be a list of NodeIdList objects')
return(internalLink)
}

return(new("Partitions", S4Vectors:::SimpleList(partitions)))
}

#' @include class-Partitions.R
check_kpartite_network <- function(object) {

errors <- character()

# Check we have at least two partitions
if (length(object@partitions) < 2) {
errors <- c(errors, 'k-partite networks must have at least two partitions.')
}

# Check that all nodes are in at least one of the partitions
if (!all(getNodeIds(object@nodes) %in% getAllNodeIds(object@partitions))) {
errors <- c(errors, 'Found a node that is not in any partition. All nodes must be assigned to a partition.')
} else if (any(sapply(getLinks(object), isLinkWithinPartition, object@partitions))) {
# Check that there are no links connecting nodes within a partition, only across the different partitions
# this check wont work if a node is missing from a partition
errors <- c(errors, 'Found a link between nodes in the same partition. Links between nodes in the same partition are not allowed.')
}
if (!all(getAllNodeIds(object@partitions) %in% getNodeIds(object@nodes))) {
errors <- c(errors, 'Found an id in a partition that is not in the nodes list. All partitions must must include ids in the nodes list.')
errors <- c(errors, 'Found an node id in a partition that is not in the nodes list. Node IDs must be consistent between partitions and nodes slots.')
}




# Check that linkColorScheme is one of the accepted values
if (!object@linkColorScheme %in% c('none', 'posneg')) {
errors <- c(errors, 'linkColorScheme must be one of "none" or "posneg"')
Expand Down Expand Up @@ -116,4 +85,86 @@ KPartiteNetwork <- setClass("KPartiteNetwork",
partitions = Partitions()
),
validity = check_kpartite_network
)
)

d-callan marked this conversation as resolved.
Show resolved Hide resolved
#' @include utils.R
#' Generate a K-Partite Network
#'
#' Generate a K-Partite Network from a LinkList and NodeList, or from a data.frame
#' @param object Object containing data to be converted to a Network
#' @param links LinkList
#' @param nodes NodeList
#' @param partitions Partitions
#' @param linkColorScheme string defining the type of coloring scheme the links follow. Options are 'none' (default) and 'posneg'.
#' @param variables VariableMetadataList
#' @return KPartiteNetwork
#' @export
#' @examples
#' KPartiteNetwork(data.frame(source='a',target='b'))
setGeneric("KPartiteNetwork",
function(
object,
links,
nodes,
partitions = Partitions(),
linkColorScheme = 'none',
variables = VariableMetadataList(),
...
) standardGeneric("KPartiteNetwork"),
signature = c("object", "links", "nodes")
)

#' @export
setMethod("KPartiteNetwork", signature("missing", "LinkList", "NodeList"), function(
object,
links,
nodes,
partitions = Partitions(),
linkColorScheme = 'none',
variables = VariableMetadataList(),
...
) {
new("KPartiteNetwork", links=links, nodes=nodes, partitions=partitions, linkColorScheme=linkColorScheme, variableMapping=variables)
})

#' @export
setMethod("KPartiteNetwork", signature("data.frame", "missing", "missing"), function(
object = data.frame(source=character(),target=character()),
links,
nodes,
partitions = Partitions(),
linkColorScheme = 'none',
variables = VariableMetadataList(),
...
) {
new("KPartiteNetwork", links=LinkList(object), nodes=NodeList(object), partitions=partitions, linkColorScheme=linkColorScheme, variableMapping=variables)
d-callan marked this conversation as resolved.
Show resolved Hide resolved
})

#' @export
setMethod("KPartiteNetwork", signature("Network", "missing", "missing"), function(
object,
links,
nodes,
partitions = Partitions(),
linkColorScheme = 'none',
variables = VariableMetadataList(),
...
) {
nodes <- object@nodes
links <- object@links

new("KPartiteNetwork", links=links, nodes=nodes, partitions=partitions, linkColorScheme=linkColorScheme, variableMapping=variables)
})

#' @export
setMethod("KPartiteNetwork", signature("missing", "missing", "missing"), function(
object,
links,
nodes,
partitions = Partitions(),
linkColorScheme = 'none',
variables = VariableMetadataList(),
...
) {
new("KPartiteNetwork")
})
Loading
Loading