Nothing
## bit array adjacency matrix representation of a graph
setMethod("initialize", signature("graphBAM"),
function(.Object, nodes,edgeSet) {
.Object@graphData$edgemode <-
if (isDirected(edgeSet)) "directed" else "undirected"
.Object@renderInfo@edges <- list(arrowhead=NULL, arrowtail=NULL)
.Object@nodeData <- new("attrData")
.Object@edgeData <- new("attrData")
.Object@nodes <- nodes
.Object@edgeSet <- edgeSet
.Object
})
graphBAM <- function(df, nodes = NULL, edgemode = "undirected",
ignore_dup_edges = FALSE)
{
.required <- c("from", "to", "weight")
cl <- .required %in% names(df)
if (!all(cl)) {
stop("required 'names(df)' not present: ",
pasteq(.required[!cl]))
}
if (any(duplicated(nodes)))
stop(sQuote(nodes), " must be unique")
edge_nodes <- unique(c(as.character(df$from), as.character(df$to)))
if (!all(edge_nodes %in% nodes))
nodes <- sort(c(edge_nodes, nodes))
else if (is.null(nodes))
nodes <- edge_nodes
is_directed <- edgemode == "directed"
edge_sets <- .makeMDEdgeSet(es_name = 1, es = df,
is_directed = is_directed, nodes,
ignore_dup_edges = ignore_dup_edges)
g <- new("graphBAM", nodes = nodes, edgeSet = edge_sets)
g@edgeData@defaults[["weight"]] <- 1L
g
}
setMethod("numEdges", signature = signature(object = "graphBAM"),
function(object) {
numEdges(object@edgeSet)
})
.undirectEdges <- function(from, to)
{
fromIsFirst <- from <= to
toIsFirst <- !fromIsFirst
tmpFrom <- c(from[fromIsFirst], to[toIsFirst])
tmpTo <- c(to[fromIsFirst], from[toIsFirst])
from <- tmpFrom
to <- tmpTo
list(from=from, to=to)
}
.edges_gbam <- function(object, which, direction="out")
{
nn <- nodes(object)
if (numEdges(object) == 0L) {
names(nn) <- nn
c0 <- character(0L)
return(lapply(nn, function(x) c0))
}
ft <- .Call(graph_bitarray_rowColPos, object@edgeSet@bit_vector)
ft[] <- nn[ft]
eL <- singles <- NULL
if (isDirected(object)) {
if (direction == "in")
ft[ , c("from", "to")] <- ft[ , c("to", "from")]
eL <- split(ft[ , "to"], ft[ , "from"])
singles <- nn[!(nn %in% ft[ , "from"])]
} else {
eL <- lapply(split(ft, ft[ , c("to", "from")]), unique)
singles <- nn[!(nn %in% ft)]
}
if (length(singles) > 0) {
names(singles) <- singles
c0 <- character(0L)
empties <- lapply(singles, function(x) c0)
eL <- c(eL, empties)
}
eL[order(names(eL))]
}
setMethod("inEdges", signature("character", "graphBAM"),
function(node, object) {
.edges_gbam(object, direction = "in")[node]
})
setMethod("edges", signature("graphBAM"),
function(object, which, direction="out") {
if (missing(which))
return(.edges_gbam(object, which, direction))
if (!missing(direction))
warning("'direction' is ignored when 'which' is specified")
## TODO: refactor to optimize
.edges_gbam(object)[which]
})
setMethod("adj", c("graphBAM", "character"),
function(object, index) edges(object, index))
getWeightList2 <- function(g){
nodeNames <- g@nodes
numNodes <- length(nodeNames)
w <- g@edgeSet@weights
ft <- .Call(graph_bitarray_rowColPos, g@edgeSet@bit_vector)
if(!isDirected(g)){
ft <- rbind(ft, ft[ , c(2L, 1L)])
w <- c(w,w)
}
ft[] <- nodeNames[ft]
wList <- split(w, ft[ , 1L])
wNameList <- split(ft[ , 2L], ft[ , 1L])
wList <- mapply(function(wVals, wNames) {
names(wVals) <- wNames
a <- wVals[order(wNames)]
if (!isDirected(g)) a[!duplicated(names(a))] else a
}, wList, wNameList, SIMPLIFY=FALSE)
haveNoEdge <- setdiff(nodeNames, names(wList))
names(haveNoEdge) <- haveNoEdge
n0 <- numeric(0)
haveNoEdge <- lapply(haveNoEdge, function(x) n0)
c(wList, haveNoEdge)[nodeNames]
}
setMethod("edgeWeights", signature(object="graphBAM", index="character"),
function(object, index, attr, default, type.checker)
{
if (!is.character(attr) || length(attr) != 1)
stop("'attr' must be character(1)")
if (!is.null(type.checker) && !is.function(type.checker))
stop("'type.checker' must be a function or NULL")
getWeightList2(object)[index]
})
setMethod("edgeWeights", signature(object="graphBAM", index="numeric"),
function(object, index, attr, default, type.checker)
{
edgeWeights(object, nodes(object)[index], attr=attr,
default=default, type.checker=type.checker)
})
setMethod("edgeWeights", signature(object="graphBAM", index="missing"),
function(object, index, attr, default, type.checker)
{
edgeWeights(object, nodes(object), attr=attr, default=default,
type.checker=type.checker)
})
.eAttrsFun <- function(self, from, attr) {
nodeNames <- self@nodes
indx <- which(nodeNames %in% from)
numNodes <- length(nodeNames)
bv <- self@edgeSet@bit_vector
.verifyBAMAttrs(self, attr)
val <- .retAttrVec(self, attr)
ft <- .Call(graph_bitarray_rowColPos, bv)
if(!isDirected(self)){
df <- cbind(from=ft[,"to"], to = ft[,"from"])
ft <- rbind(ft,df)
val <- c(val,val)
}
tmp <- seq_len(length(val)) # indices into val
ft <- data.frame(ft, tmp, stringsAsFactors = FALSE )
ft <- ft[ ft[,"from"] %in% indx,]
if(nrow(ft) == 0)
stop("edges specified in 'from' not found in 'self'")
nodeLbl <- paste( nodeNames[ft[,"from"]], nodeNames[ft[, "to"]],
sep ="|")
val <- val[ft[,"tmp"]][seq_along(nodeLbl)]
names(val) <- nodeLbl
val
}
## graphBAM edgeData methods
setMethod("edgeData",
signature(self="graphBAM", from="character", to= "missing", attr="character"),
function(self, from, to, attr){
as.list(.eAttrsFun(self, from, attr))
})
setMethod("edgeData",
signature(self="graphBAM", from="character", to="character", attr="character"),
function(self, from, to, attr) {
edgeData.from <- edgeData(self, attr=attr, from=from)
unrecognized.nodes <- setdiff(to, nodes(self))
if(length(unrecognized.nodes) > 0) {
msg <- sprintf("nodes not in graph: %s",
paste(sQuote(unrecognized.nodes), collapse=", "))
stop(msg)
}
edgeNames <- names(edgeData.from)
toStarts <- regexpr("|", edgeNames, fixed=TRUE) + 1L
actual.to.nodes <- substring(edgeNames, toStarts, nchar(edgeNames))
edgeData.from[actual.to.nodes %in% to]
})
setMethod("edgeData",
signature(self="graphBAM", from="missing", to= "character", attr="character"),
function(self, from, to, attr){
nodeNames <- self@nodes
numNodes <- length(nodeNames)
bv <- self@edgeSet@bit_vector
.verifyBAMAttrs(self, attr)
val <- .retAttrVec(self, attr)
ft <- .Call(graph_bitarray_rowColPos, self@edgeSet@bit_vector)
if(!isDirected(self)){
df <- cbind(from=ft[,"to"], to = ft[,"from"])
ft <- rbind(ft,df)
val <- c(val,val)
}
tmp <- seq_len(length(val))
ft <- data.frame(ft, tmp, stringsAsFactors = FALSE)
ft <- ft[ft[,"to"] %in% which(nodeNames %in% to),]
if(nrow(ft) == 0)
stop("edges specified in 'to' not found in 'self'")
.verifyEdges(self, nodeNames[ft[,"from"]], nodeNames[ft[,"to"]])
nodeLbl <- paste( nodeNames[ft[,"from"]], nodeNames[ft[, "to"]],
sep ="|")
val <- val[ft[,"tmp"]][seq_along(nodeLbl)]
names(val) <- nodeLbl
as.list(val)
})
setMethod("edgeData",
signature(self="graphBAM", from="missing", to="missing", attr="missing"),
function(self, from, to, attr) {
nodeNames <- self@nodes
numNodes <- length(nodeNames)
attr <- "weight"
bv <- self@edgeSet@bit_vector
ft <- .Call(graph_bitarray_rowColPos, bv)
w <- .retAttrVec(self, attr)
if(!isDirected(self)){
df <- cbind(from=ft[,"to"], to = ft[,"from"])
ft <- rbind(ft,df)
w <- c(w,w)
}
nodeLbl <- paste( nodeNames[ft[,"from"]], nodeNames[ft[, "to"]],
sep ="|")
names(w) <- nodeLbl
lapply(w, function(x) list(weight = as.numeric(x)))
})
setMethod("edgeData",
signature(self="graphBAM", from="missing", to= "missing", attr="character"),
function(self, from, to, attr){
as.list(.eAttrsFun(self, from = names(edges(self)), attr= attr))
})
.retAttrVec <- function(g, attr) {
if(attr !="weight") {
k1 <- g@edgeSet@bit_vector
k2<- g@userAttrPos@edgePos[[attr]]
tmp <- attributes(k1)
res <- k1& (!k2)
attributes(res) <- tmp
ns <- .Call(graph_bitarray_sum, res)
attr(res, "nbitset") <- ns
ft <- data.frame(.Call(graph_bitarray_rowColPos, res),
stringsAsFactors = TRUE)
dflt <- g@edgeData@defaults[[attr]]
attrBit <- g@userAttrPos@edgePos[[attr]]
ft <- ft[with(ft, order(to, from)),]
if(nrow(ft)) {
ord <- .Call(graph_bitarray_getEdgeAttrOrder, attrBit,
as.integer(ft[,"from"]), as.integer(ft[,"to"]))
attrBit <- setBitCell(attrBit, ft[,"from"], ft[,"to"],
rep(1L, nrow(ft)))
nt <- attr(attrBit, "nbitset")
} else {
nt <- attr(attrBit, "nbitset")
ord <- list(newLeftPos = integer(0), newRightPos = integer(0),
origLeftPos = seq_len(nt), origRightPos = seq_len(nt))
}
newAttr <- vector(nt, mode = mode(dflt))
if(!is.null(g@edgeSet@edge_attrs[[attr]])) {
newAttr[ord$origLeftPos] <- g@edgeSet@edge_attrs[[attr]][ord$origRightPos]
newAttr[ord$newLeftPos] <- if(mode(dflt)=="list") rep(list(dflt), length(ord$newLeftPos)) else dflt
}else{
newAttr[seq_len(nt)] <-
if(mode(dflt)=="list") rep(list(dflt), nt) else dflt
}
}else{
newAttr <- g@edgeSet@weights
}
newAttr
}
.align_from_to <- function(from, to, nodeNames)
{
from_len <- length(from)
to_len <- length(to)
req_nn <- unique(c(from, to))
if (!all(okidx <- req_nn %in% nodeNames))
stop("unknown nodes: ", pasteq(req_nn[!okidx]))
if (from_len != to_len) {
if (from_len == 1L)
from <- rep(from, to_len)
else if (to_len == 1L)
to <- rep(to, from_len)
else
stop("invalid lengths of 'from' and 'to'")
}
df <- cbind(from=from, to=to)
}
.verifyBAMAttrs <- function(bam, attr) {
if( !(attr %in% names(bam@edgeData@defaults)))
stop("'attr' not found: ", sQuote(attr))
}
.set_attrs <- function(g, from, to, attr, value)
{
nodeNames <- g@nodes
req_ft <- .align_from_to(from, to, nodeNames)
## remove dups
indx <- duplicated(paste(req_ft[,"from"], req_ft[,"to"], sep ="_"))
req_ft <- req_ft[!indx, ,drop = FALSE]
if(nrow(req_ft) > 0 )
.verifyEdges(g, req_ft[,1], req_ft[,2])
else
stop("edges specified could not be found in \"self\"")
if(is.vector(value)) {
len <- length(value)
}else{
len <- 1
value <- list(value)
}
if(len == 1L)
value <- rep(value, nrow(req_ft))
if(length(value) != nrow(req_ft))
stop("number of edges and attribute values must be the same")
ft <- .Call(graph_bitarray_rowColPos, g@edgeSet@bit_vector)
if (!isDirected(g)) {
## normalize from/to
valIndx <- seq_len(length(value))
tmp <- .mg_undirectEdges(req_ft[ , 1], req_ft[, 2], valIndx)
req_ft <- cbind("from"= tmp[["from"]],"to" = tmp[["to"]])
value <- value[tmp[["weight"]]]
}
req_i <- structure(match(req_ft, nodeNames), dim = dim(req_ft))
colnames(req_i) <- c("from", "to")
req_i <- data.frame(req_i, stringsAsFactors = TRUE)
idx <- order(req_i[,2], req_i[,1])
req_i <- req_i[idx, ]
value <- value[idx]
if(attr == "weight") {
attrBit <- g@edgeSet@bit_vector
if(nrow(req_i)) {
ord <- .Call(graph_bitarray_getEdgeAttrOrder, attrBit,
as.integer(req_i[,"from"]), as.integer(req_i[,"to"]))
g@edgeSet@bit_vector <- setBitCell(attrBit, req_i[,"from"], req_i[,"to"],
rep(1L, nrow(req_i)))
nt <- attr(g@edgeSet@bit_vector, "nbitset")
} else {
nt <- attr(attrBit, "nbitset")
ord <- list(newLeftPos = integer(0), newRightPos = integer(0),
origLeftPos = seq_len(nt), origRightPos = seq_len(nt))
}
newAttr <- vector(nt, mode = mode(value))
newAttr[ord$origLeftPos] <- g@edgeSet@weights[ord$origRightPos]
newAttr[ord$newLeftPos] <- value[ord$newRightPos]
g@edgeSet@weights <- newAttr
}else {
attrBit <- g@userAttrPos@edgePos[[attr]]
if(nrow(req_i)) {
ord <- .Call(graph_bitarray_getEdgeAttrOrder, attrBit,
as.integer(req_i[,"from"]), as.integer(req_i[,"to"]))
g@userAttrPos@edgePos[[attr]] <- setBitCell(attrBit, req_i[,"from"], req_i[,"to"],
rep(1L, nrow(req_i)))
nt <- attr(g@userAttrPos@edgePos[[attr]], "nbitset")
} else {
nt <- attr(attrBit, "nbitset")
ord <- list(newLeftPos = integer(0), newRightPos = integer(0),
origLeftPos = seq_len(nt), origRightPos = seq_len(nt))
}
newAttr <- vector(nt, mode = mode(value))
newAttr[ord$origLeftPos] <-
g@edgeSet@edge_attrs[[attr]][ord$origRightPos]
newAttr[ord$newLeftPos] <- value[ord$newRightPos]
g@edgeSet@edge_attrs[[attr]] <- newAttr
}
g
}
## graphBAM edgeData replacement methods
setReplaceMethod("edgeData",
signature(self="graphBAM",
from="character", to="character",
attr="character", value="ANY"),
function(self, from, to, attr, value) {
.verifyAttrName(attr, names(self@edgeData@defaults))
lenFrom <- length(from)
lenTo <- length(to)
if(lenFrom != lenTo) {
if(lenFrom ==1)
from <- rep(from, lenTo)
else if (lenTo == 1)
to <- rep(to , lenFrom)
else
stop("'from', 'to' differ in length")
}
.verifyEdges(self, from, to)
.set_attrs(self, from, to, attr, value)
})
setReplaceMethod("edgeData",
signature(self="graphBAM",
from="character", to="missing",
attr="character", value="ANY"),
function(self, from, to, attr, value) {
.verifyAttrName(attr, names(self@edgeData@defaults))
eg <- edges(self,from)
to <- unlist(eg, use.names = FALSE)
len <- as.numeric(sapply(eg, length))
from <- rep(names(eg),len)
.verifyEdges(self, from, to)
.set_attrs(self, from, to, attr, value)
})
setReplaceMethod("edgeData",
signature(self="graphBAM",
from="missing", to="character",
attr="character", value="ANY"),
function(self, from, to, attr, value) {
.verifyAttrName(attr, names(self@edgeData@defaults))
eg <- inEdges(to, self)
eg <- eg[order(names(eg))]
from <- unlist(eg, use.names = FALSE)
len <- as.numeric(sapply(eg, length))
to <- rep(names(eg), len)
.verifyEdges(self, from, to)
.set_attrs(self, from, to, attr, value)
})
## graphBAM edgeDataDefaults replacement methods
setReplaceMethod("edgeDataDefaults", signature(self="graphBAM", attr="missing",
value="list"),
function(self, attr, value) {
attrDefaults(self@edgeData) <- value
wt <- self@edgeData@defaults[["weights"]]
if(!is.numeric(wt) && !is.null(wt))
stop("'weights' attribute must be numeric()")
ndsLen <- length(nodes(self))
nms <- names(value)
for(i in seq_along(value)) {
if(!(nms[i] %in% names(self@userAttrPos@edgePos))) {
if(nms[i] != "weight"){
posBit <- .createZeroBitPos(ndsLen)
self@userAttrPos@edgePos[[nms[i]]] <- posBit
}
}
}
self
})
setReplaceMethod("edgeDataDefaults", signature(self="graphBAM", attr="character",
value="ANY"),
function(self, attr, value) {
attrDefaults(self@edgeData, attr) <- value
if(attr == "weight") {
wt <- self@edgeData@defaults[["weights"]]
if(!is.numeric(wt) && !is.null(wt))
stop("'weights' attribute must be numeric()")
} else{
ndsLen <- length(nodes(self))
if(!(attr %in% names(self@userAttrPos@edgePos))) {
posBit <- .createZeroBitPos(ndsLen)
self@userAttrPos@edgePos[[attr]] <- posBit
}
}
self
})
.createZeroBitPos <- function(ndsLen) {
makebits(ndsLen * ndsLen, bitdim = c(ndsLen, ndsLen))
}
setMethod("numNodes", signature("graphBAM"),
function(object) length(object@nodes))
setMethod("isAdjacent",
signature(object="graphBAM", from="character", to="character"),
function(object, from, to) {
if(length(from) > 1 & length(to) == 1)
to <- rep(to, length(from))
if(length(to) > 1 & length(from) == 1)
from <- rep(from, length(to))
stopifnot(length(from) == length(to))
nodeNames <- object@nodes
edge.matrix <- edgeMatrix(object)
edge.count <- ncol(edge.matrix)
reciprocal.edges <- edgemode(object) == "undirected"
result <- rep(FALSE, length(from))
pair.count <- length(from)
for(pc in seq_len(pair.count)) {
for(ec in seq_len(edge.count)){
from.node <- nodeNames[edge.matrix["from", ec]]
to.node <- nodeNames[edge.matrix["to", ec]]
if(from.node == from[pc] & to.node == to[pc]){
result[pc] <- TRUE
break;
}
if(reciprocal.edges & to.node == from[pc] & from.node == to[pc]){
result[pc] <- TRUE
break;
}
} # for ec
} # for pc
result
}) # isAdjacent
setMethod("subGraph", signature(snodes="character", graph="graphBAM"),
function(snodes, graph){
origNodes <- nodes(graph)
snodes <- sort(snodes)
snodesIdx <- match(snodes, origNodes)
if (any(is.na(snodesIdx))) {
bad <- snodes[which(is.na(snodesIdx))]
stop("'snodes' not in MultiGraph: ", pasteq(bad))
}
nms <- names(graph@nodeData@defaults)
len <- length(snodes)
tmp <- makebits(len)
for(i in nms){
indx <- bitToLogical(graph@userAttrPos@nodePos[[i]])[snodesIdx]
graph@nodeData@data[[i]] <- .getNodeAttrVec(graph, i)[snodesIdx][indx]
graph@userAttrPos@nodePos[[i]] <- setbitv(tmp, which(indx), rep(1L, length(which(indx))))
}
graph@nodes <- snodes
res <- .Call(graph_bitarray_subGraph, graph@edgeSet@bit_vector, snodesIdx)
graph@edgeSet@bit_vector <- res$bitVec
graph@edgeSet@weights <- graph@edgeSet@weights[res$setPos]
nms <- names(graph@edgeSet@edge_attrs)
for(i in nms) {
attrBit <- graph@userAttrPos@edgePos[[i]]
res <- .Call(graph_bitarray_subGraph, attrBit, snodesIdx)
graph@edgeSet@edge_attrs[[i]] <- graph@edgeSet@edge_attrs[[i]][res$setPos]
graph@userAttrPos@edgePos[[i]] <- res$bitVec
}
graph
})
setMethod("edgeMatrix", "graphBAM",
function(object, duplicates=FALSE) {
bitvec <- object@edgeSet@bit_vector
nds <- nodes(object)
df <- .Call(graph_bitarray_rowColPos, bitvec)
if (duplicates)
df <- rbind(df, cbind(as.vector(df[, "to"]),
as.vector(df[, "from"])))
t(df)
})
setMethod("adjacencyMatrix", "graphBAM",
function(object) {
reciprocal.edges <- edgemode(object) == "undirected";
em <- edgeMatrix(object)
nodes <- nodes(object)
node.count <- length(nodes)
mtx.adj <- matrix(0, nrow=node.count, ncol=node.count,
dimnames=list(nodes, nodes))
for(col in 1:ncol(em)){
from <- em["from", col]
to <- em["to", col]
from.node <- nodes[from]
to.node <- nodes[to]
mtx.adj[from.node, to.node] <- 1;
if(reciprocal.edges)
mtx.adj[to.node, from.node] <- 1;
}
mtx.adj
})
setMethod("clearNode",
signature(node="character", object="graphBAM"),
function(node, object) {
stop("operation not supported")
})
setMethod("removeNode",
signature(node="character", object="graphBAM"),
function(node, object) {
nn <- nodes(object)
if(!all(node %in% nn))
stop("'node' not all in 'object'")
df <- extractFromTo(object)
indx <- ! ( (as.character(df[,"from"]) %in% node) |
(as.character(df[,"to"]) %in% node))
nIndx <- !(nn %in% node)
bam <- graphBAM(df[indx,], nodes = nn[nIndx] ,
edgemode = edgemode(object))
bam@edgeSet@weights <- object@edgeSet@weights[indx]
bam@edgeData@defaults <- object@edgeData@defaults
bam@nodeData@defaults <- object@nodeData@defaults
nms <- names(object@edgeSet@edge_attrs)
snodesIdx <- which(nIndx)
for(i in nms) {
attrBit <- object@userAttrPos@edgePos[[i]]
res <- .Call(graph_bitarray_subGraph, attrBit, snodesIdx)
bam@edgeSet@edge_attrs[[i]] <- object@edgeSet@edge_attrs[[i]][res$setPos]
bam@userAttrPos@edgePos[[i]] <- res$bitVec
}
nms <- names(object@nodeData@defaults)
len <- length(snodesIdx)
tmp <- makebits(len)
for(i in nms){
leftPos <- which(bitToLogical(object@userAttrPos@nodePos[[i]])[snodesIdx])
rightPos <- which(bitToLogical(object@userAttrPos@nodePos[[i]]))[snodesIdx]
bt <- setbitv(tmp, leftPos, rep(1L, length(leftPos)))
# k <- .getNodeAttrValues(bt, indx)
bam@userAttrPos@nodePos[[i]] <- bt
bam@nodeData@data[[i]] <- object@nodeData@data[[i]][rightPos]
}
bam
})
setMethod("extractFromTo", "graphBAM",
function(g) {
diEdgeSetToDataFrame(g@edgeSet, nodes(g))
})
setAs(from="graphBAM", to="matrix",
function(from) {
edgeSetToMatrix(nodes(from), from@edgeSet, isDirected(from))
})
setAs(from="graphBAM", to="graphAM",
function(from) {
am <- graphAM(adjMat = as(from, "matrix"),
edgemode = edgemode(from), values = list(weight=1))
am
})
setAs(from="graphBAM", to="graphNEL",
function(from) {
am <- as(from, "graphAM")
as(am, "graphNEL")
})
graphToBAM <- function(object) {
ew <- edgeWeights(object)
df_empty <- data.frame(from = character(0), to = character(0),
weight = numeric(0),
stringsAsFactors = TRUE)
df_list <- lapply(names(ew), function(x){
tmp <- ew[[x]]
if ((nw <- length(tmp)) > 0) {
data.frame(from = rep(x, nw), to = names(tmp),
weight = as.numeric(tmp),
stringsAsFactors = TRUE)
} else df_empty
})
df <- do.call(rbind, df_list)
nn <- nodes(object)
bam <- graphBAM(df, nodes = nn, edgemode = edgemode(object),
ignore_dup_edges = TRUE)
## FIXME: graphBAM doesn't really handle edge attributes in the same way
## we can copy data over so it can be copied back, but it won't really
## be accessible in the new graphBAM object.
bam
}
setAs(from="graphNEL", to="graphBAM",
function(from) as(as(from, "graphAM"), "graphBAM"))
setAs(from="graphAM", to="graphBAM",
function(from) graphToBAM(from))
setMethod("ugraph", "graphBAM",
function(graph) {
graph@graphData$edgemode <- "undirected"
graph@renderInfo <- new("renderInfo")
graph@edgeSet <- ugraph(graph@edgeSet)
graph
})
setMethod("addEdge",
signature=c("character", "character", "graphBAM", "numeric"),
function(from, to, graph, weights) {
nn <- nodes(graph)
req_ft <- .align_from_to(from, to, nn)
req_i <- structure(match(req_ft, nn), dim = dim(req_ft))
if(nrow(req_i)) {
ord <- .Call(graph_bitarray_getEdgeAttrOrder,
graph@edgeSet@bit_vector,
as.integer(req_i[,1]), as.integer(req_i[,2]))
graph@edgeSet@bit_vector <-
setBitCell(graph@edgeSet@bit_vector, req_i[,1], req_i[,2],
rep(1L, nrow(req_i)))
nt <- attr(graph@edgeSet@bit_vector, "nbitset")
} else {
nt <- attr(graph@edgeSet@bit_vector, "nbitset")
ord <- list(newLeftPos = integer(0), newRightPos = integer(0),
origLeftPos = seq_len(nt), origRightPos = seq_len(nt))
}
newAttr <- vector(nt, mode = "numeric")
newAttr[ord$origLeftPos] <- graph@edgeSet@weights[ord$origRightPos]
newAttr[ord$newLeftPos] <- weights[ord$newRightPos]
graph@edgeSet@weights <- newAttr
graph@edgeData@defaults <- graph@edgeData@defaults
graph@edgeSet@edge_attrs <- graph@edgeSet@edge_attrs
graph@userAttrPos@edgePos <- graph@userAttrPos@edgePos
graph@nodeData@defaults <- graph@nodeData@defaults
graph@nodeData@data <- graph@nodeData@data
graph@userAttrPos@nodePos <- graph@userAttrPos@nodePos
graph
})
setMethod("addEdge",
signature=c("character", "character", "graphBAM", "missing"),
function(from, to, graph, weights) {
w <- rep(1L, max(length(from), length(to)))
addEdge(from, to, graph, w)
})
setMethod("addNode",
signature(node="character", object="graphBAM", edges="missing"),
function(node, object) {
nds <- sort(unique(c(nodes(object), node)))
ndsLen <- length(nds)
df <- extractFromTo(object)
g <- graphBAM(df, nodes = nds, edgemode = edgemode(object))
nms <- names(object@nodeData@defaults)
for(i in nms){
origNds <- nodes(object)[(bitToLogical(object@userAttrPos@nodePos[[i]]))]
indx <- match(origNds, nodes(g))
bt <- makebits(ndsLen)
bt <- setbitv(bt, indx, rep(1L, length(indx)))
g@userAttrPos@nodePos[[i]] <- bt
g@nodeData@data[[i]] <- object@nodeData@data[[i]]
}
g@nodeData@defaults <- object@nodeData@defaults
g@edgeSet@edge_attrs <- object@edgeSet@edge_attrs
g@edgeData@defaults <- object@edgeData@defaults
nms <- names(object@userAttrPos@edgePos)
for(i in nms){
ft <- .Call(graph_bitarray_rowColPos,object@userAttrPos@edgePos[[i]])
posBit <- .createZeroBitPos(ndsLen)
from.nodes.new <- match(nodes(object)[ft[, 'from']], nodes(g))
to.nodes.new <- match(nodes(object)[ft[, 'to']], nodes(g))
g@userAttrPos@edgePos[[i]] <- setBitCell(posBit,
from.nodes.new,
to.nodes.new,
rep(1L, nrow(ft)))
}
g
})
setReplaceMethod("edgemode", c("graphBAM", "character"),
function(object, value)
{
if (length(value) != 1L) stop("'edgemode' must be length one")
if (edgemode(object) == value) return(object)
switch(value,
"directed" = {
## add reciprocal edges
df <- extractFromTo(object)
es <- rbind(df,
data.frame(from=df$to, to=df$from,
weight=df$weight,
stringsAsFactors=FALSE))
object <- graphBAM(es, nodes = nodes(object),
edgemode = value)
},
"undirected" = {
object <- ugraph(object)
},
stop("'edgemode' must be 'directed' or 'undirected', was ",
sQuote(value)))
object
})
.remEdge <- function(from, to, graph)
{
lenFrom <- length(from)
lenTo <- length(to)
if(lenFrom != lenTo) {
if(lenFrom ==1)
from <- rep(from, lenTo)
else if (lenTo == 1)
to <- rep(to , lenFrom)
else
stop("arguments 'from', 'to' differ in length")
}
.verifyEdges(graph, from, to)
nn <- nodes(graph)
req_ft <- .align_from_to(from, to, nn)
req_from <- match(req_ft[,"from"], nn)
req_to <- match(req_ft[,"to"], nn)
nms <- names(graph@edgeSet@edge_attrs)
if(!is.null(nms)) {
for(i in nms){
graph@userAttrPos@edgePos[[i]] <-
setBitCell(graph@userAttrPos@edgePos[[i]], req_from, req_to,
rep(0L, nrow(req_ft)))
if(length(req_from)) {
ord <- .Call(graph_bitarray_getEdgeAttrOrder, graph@userAttrPos@edgePos[[i]],
as.integer(req_from), as.integer(req_to))
} else {
nt <- attr(graph@userAttrPos@edgePos[[i]], "nbitset")
ord <- list(newLeftPos = integer(0), newRightPos = integer(0),
origLeftPos = seq_len(nt), origRightPos = seq_len(nt))
}
graph@edgeSet@edge_attrs[[i]] <- graph@edgeSet@edge_attrs[[i]][ord$origLeftPos]
}
}
obv0 <- graph@edgeSet@bit_vector
graph@edgeSet@bit_vector <- setBitCell(graph@edgeSet@bit_vector,
match(from, nn),
match(to, nn),
rep(0L, nrow(req_ft)))
nbv0 <- graph@edgeSet@bit_vector
ord <- .Call(graph_bitarray_getEdgeAttrOrder, graph@edgeSet@bit_vector ,
as.integer(req_from), as.integer(req_to))
graph@edgeSet@weights <- graph@edgeSet@weights[ord$origLeftPos]
if(edgemode(graph) == "undirected"){ # reverse from/to
obv1 <- graph@edgeSet@bit_vector
graph@edgeSet@bit_vector <- setBitCell(graph@edgeSet@bit_vector,
match(to, nn),
match(from, nn),
rep(0L, nrow(req_ft)))
nbv1 <- graph@edgeSet@bit_vector
ord <- .Call(graph_bitarray_getEdgeAttrOrder, graph@edgeSet@bit_vector ,
as.integer(req_from), as.integer(req_to))
graph@edgeSet@weights <- graph@edgeSet@weights[ord$origLeftPos]
} # if undirected
graph
}
setMethod("removeEdge", c("character", "character", "graphBAM"),
function(from, to, graph) .remEdge(from, to, graph))
setMethod("removeEdgesByWeight", c("graphBAM"),
function(graph, lessThan, greaterThan ){
if(missing(lessThan) && missing(greaterThan))
stop("specify 'lessThan' or 'greaterThan'")
if(!missing(lessThan) && !missing(greaterThan)){
indx <- ( graph@edgeSet@weights >= lessThan &
graph@edgeSet@weights <= greaterThan)
} else if(missing(lessThan)){
indx <- graph@edgeSet@weights <= greaterThan
}else if(missing(greaterThan)){
indx <- graph@edgeSet@weights >= lessThan
}
nn <- nodes(graph)
bt <- .Call(graph_bitarray_removeEdges, graph@edgeSet@bit_vector, indx)
tempBit <- graph@edgeSet@bit_vector & (bt)
attributes(tempBit) <- attributes(graph@edgeSet@bit_vector)
attr(tempBit, "nbitset") <- .Call(graph_bitarray_sum, tempBit)
ft <- .Call(graph_bitarray_rowColPos, tempBit)
tp <- graph@edgeSet@bit_vector & (!bt)
attributes(tp) <- attributes(graph@edgeSet@bit_vector)
attr(tp, "nbitset") <- .Call(graph_bitarray_sum, tp)
ft2 <- .Call(graph_bitarray_rowColPos, tp)
graph@edgeSet@weights <- graph@edgeSet@weights[indx]
graph@edgeSet@bit_vector <- bt
nms <- names(graph@userAttrPos@edgePos)
if(!is.null(nms)){
for(i in nms) {
graph@userAttrPos@edgePos[[i]] <-
setBitCell(graph@userAttrPos@edgePos[[i]],
ft2[,"from"], ft2[,"to"], rep(0L, nrow(ft2)))
if(nrow(ft2)) {
ord <- .Call(graph_bitarray_getEdgeAttrOrder,
graph@userAttrPos@edgePos[[i]], as.integer(ft2[,"from"]),
as.integer(ft2[, "to"]))
} else {
nt <- attr(graph@userAttrPos@edgePos[[i]], "nbitset")
ord <- list(newLeftPos = integer(0), newRightPos = integer(0),
origLeftPos = seq_len(nt), origRightPos = seq_len(nt))
}
graph@edgeSet@edge_attrs[[i]] <-
graph@edgeSet@edge_attrs[[i]][ord$origLeftPos]
}
}
graph
})
setReplaceMethod("nodes", c("graphBAM", "character"),
function(object, value) {
stop("operation not supported")
})
.getUnionWeights <- function(attrType, g1, g2, funList) {
len <- length(attrType$from)
attr1 <- vector(len, mode = "numeric")
attr1[seq_len(len)] <- NA
## from x
k <- (as.numeric(attrType$from) ==1)
attr1[k] <- g1@edgeSet@weights[attrType$indx1[k]]
## from y
k <- (as.numeric(attrType$from) == 2)
attr1[k] <- g2@edgeSet@weights[attrType$indx2[k]]
## resolve union
k <- (as.numeric(attrType$from) ==0)
if(any(k)) {
val1 <- g1@edgeSet@weights[attrType$indx1[k]]
val2 <- g2@edgeSet@weights[attrType$indx2[k]]
if(!is.null(funList) && ("weight" %in% names(funList))) {
attr1[k] <- sapply(seq_len(sum(k)), function(p) {
return(funList[["weight"]](val1[[p]], val2[[p]]))
})
} else if(is.vector(val1) && is.vector(val2)) {
eqInd <- sapply(seq_len(length(val1)), function(x){
identical(val1[x], val2[x])
})
pt <- which(eqInd)
lp <- length(which(k))
tmp <- vector(lp, mode ="numeric")
tmp[seq_len(lp)] <- NA
tmp[pt] <- val1[pt]
attr1[k] <- tmp
}
}
attr1
}
.getNodeAttrVec <- function(g, att) {
unlist(nodeData(g, attr = att), use.names = FALSE)
}
.getUnionAttrs <- function(att, attrType, x , y, funList ) {
len <- length(attrType$from)
indx <- as.numeric(attrType$from)
if(att %in% names(x@edgeSet@edge_attrs))
mds <- mode(x@edgeSet@edge_attrs)
else if(att %in% names(y@edgeSet@edge_attrs))
mds <- mode(y@edgeSet@edge_attrs)
attr1 <- vector(len , mode = mds)
attr1[seq_len(len)] <- NA
## from x
k <- (as.numeric(attrType$from) ==1)
if(att %in% names(x@edgeSet@edge_attrs)) {
xAttr <- .retAttrVec(x, att)
attr1[k] <- xAttr[ attrType$indx1[k]]
}
## from y
k <- (as.numeric(attrType$from) == 2)
if(att %in% names(y@edgeSet@edge_attrs)) {
yAttr <- .retAttrVec(y, att)
attr1[k] <- yAttr[ attrType$indx2[k]]
}
## resolve union
k <- (as.numeric(attrType$from) ==0)
if(any(k)) {
if(att %in% names(x@edgeSet@edge_attrs))
val1 <- xAttr[ attrType$indx1[k]]
else
val1 <- yAttr[ attrType$indx2[k]]
if(att %in% names(y@edgeSet@edge_attrs))
val2 <- yAttr[ attrType$indx2[k]]
else
val2 <- xAttr[ attrType$indx1[k]]
if(!is.null(funList) && (att %in% names(funList))) {
attr1[k] <- sapply(seq_len(sum(k)), function(p) {
return(funList[[att]](val1[[p]], val2[[p]]))
})
} else if (is.vector(val1) && is.vector(val2)) {
eqInd <- sapply(seq_len(length(val1)), function(x){
identical(val1[x], val2[x])
})
pt <- which(eqInd)
lp <- sum(k)
tmp <- vector(lp, mode = mds)
tmp[seq_len(lp)] <- NA
tmp[pt] <- val1[pt]
attr1[k] <- tmp
}
}
attr1
}
.getEdgeIntersect <- function(e1, e2) {
dr1 <- isDirected(e1)
dr2 <- isDirected(e1)
if(dr1 != dr2)
stop("edges should both be directed or undirected")
theMode <- if (dr1 && dr2) "directed" else "undirected"
e1Attr <- names(e1@edge_attrs)
e2Attr <- names(e2@edge_attrs)
commonAttr <- intersect(e1Attr, e2Attr)
bv <- e1@bit_vector & e2@bit_vector
attributes(bv) <- attributes(e1@bit_vector)
attr(bv, "nbitset") <- ns <- .Call(graph_bitarray_sum, bv)
c0 <- character(0)
df <- data.frame(from = c0, to = c0, weight = numeric(0),
stringsAsFactors = FALSE)
edge_set <- .makeMDEdgeSet(es_name = 1, es = df,
is_directed = (theMode == "directed"), nodes = c0,
ignore_dup_edges = FALSE)
edge_set@bit_vector <- bv
edge_set
}
.getBAMIntersect <- function(g1, g2, edge_set, funList) {
nn <- intersect(nodes(g1), nodes(g2))
ans <- new("graphBAM", edgeSet= edge_set, nodes =nn)
e1Attr <- names(g1@edgeSet@edge_attrs)
e2Attr <- names(g2@edgeSet@edge_attrs)
commonAttr <- intersect(e1Attr, e2Attr)
attrType <- .Call(graph_bitarray_Intersect_Attrs, edge_set@bit_vector,
g1@edgeSet@bit_vector, g2@edgeSet@bit_vector)
if(!is.null(funList)) {
fIndx <- names(funList) %in% c(commonAttr, "weight")
if(!all(fIndx))
stop("attributes in 'funList' not in edge attributes: ",
pasteq(names(funList)[fIndx]))
}
if(length(attrType$from) >0) {
edge_set@weights <- .getIntersectAttrs("weight", attrType, g1@edgeSet@weights,
g2@edgeSet@weights, funList)
}
for(i in commonAttr) {
ans@userAttrPos@edgePos[[i]] <- edge_set@bit_vector
xAttr <- .retAttrVec(g1, i)
yAttr <- .retAttrVec(g2, i)
if(length(attrType$from) >0) {
edge_set@edge_attrs[[i]] <- .getIntersectAttrs(i, attrType, xAttr, yAttr, funList)
}
}
ans@edgeSet <- edge_set
ans
}
.bamIntersect <- function(g1, g2, funList) {
e1 <- g1@edgeSet
e2 <- g2@edgeSet
dr1 <- isDirected(e1)
dr2 <- isDirected(e1)
if(dr1 != dr2)
stop("edges should both be directed or undirected")
theMode <- if (dr1 && dr2) "directed" else "undirected"
e1Attr <- names(e1@edge_attrs)
e2Attr <- names(e2@edge_attrs)
commonAttr <- intersect(e1Attr, e2Attr)
if(!is.null(funList)) {
fIndx <- names(funList) %in% c(commonAttr, "weight")
if(!all(fIndx))
stop("attributes in 'funList' not in edge attributes: ",
pasteq(names(funList)[fIndx]))
}
bv <- e1@bit_vector & e2@bit_vector
attributes(bv) <- attributes(e1@bit_vector)
attr(bv, "nbitset") <- ns <- .Call(graph_bitarray_sum, bv)
c0 <- character(0)
df <- data.frame(from = c0, to = c0, weight = numeric(0),
stringsAsFactors = FALSE)
edge_set <- .makeMDEdgeSet(es_name = 1, es = df,
is_directed = (theMode == "directed"), nodes = c0,
ignore_dup_edges = FALSE)
edge_set@bit_vector <- bv
nn <- intersect(nodes(g1), nodes(g2))
ans <- new("graphBAM", edgeSet= edge_set, nodes =nn)
attrType <- .Call(graph_bitarray_Intersect_Attrs, edge_set@bit_vector,
e1@bit_vector, e2@bit_vector)
if(length(attrType$from) >0) {
edge_set@weights <- .getIntersectAttrs("weight", attrType, e1@weights,
e2@weights, funList)
}
for(i in commonAttr) {
ans@userAttrPos@edgePos[[i]] <- edge_set@bit_vector
xAttr <- .retAttrVec(g1, i)
yAttr <- .retAttrVec(g2, i)
if(length(attrType$from) >0) {
edge_set@edge_attrs[[i]] <- .getIntersectAttrs(i, attrType, xAttr, yAttr, funList)
}
}
ans@edgeSet <- edge_set
ans
}
.getUnionNodeUserAttrPos <- function(g, sg1, sg2) {
cmnAttrs <- intersect(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults))
unqAttrs <- unique(c(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults)))
singleAttrs <- unqAttrs[!( unqAttrs %in% cmnAttrs)]
n1 <- structure(lapply(cmnAttrs, function(i){
len <- length(g@nodeData@data[[i]])
bt <- makebits(len)
bt <- setbitv(bt, seq_len(len), rep(1L, len))
}),names = cmnAttrs)
n2 <- structure(lapply(singleAttrs, function(i){
if(i %in% names(sg1@userAttrPos@nodePos))
return(sg1@userAttrPos@nodePos[[i]])
else if(i %in% names(sg2@userAttrPos@nodePos))
return(sg2@userAttrPos@nodePos[[i]])
}), names= singleAttrs)
c(n1, n2)
}
.getIntNodeUserAttrPos <- function(sg1 , sg2) {
nattr <- intersect(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults))
structure(lapply(nattr, function(i) {
bv <- sg1@userAttrPos@nodePos[[i]] & sg2@userAttrPos@nodePos[[i]]
attributes(bv) <- attributes(sg1@userAttrPos@nodePos[[i]])
attr(bv, "nbitset") <- ns <- .Call(graph_bitarray_sum, bv)
bv
}), names = nattr)
}
.getIntersectAttrs <- function(att, attrType, xAtt , yAtt, funList ) {
len <- length(attrType$from)
from1 <- attrType$indx1
from2 <- attrType$indx2
k <- (as.numeric(attrType$from) ==0)
attr1 <- vector(sum(k), mode =mode(xAtt))
attr1[seq_len(sum(k))] <- NA
val1 <- xAtt[attrType$indx1[k]]
val2 <- yAtt[attrType$indx2[k]]
if(!is.null(funList) && (att %in% names(funList))) {
attr1[k] <- sapply(seq_len(sum(k)), function(p) {
return(funList[[att]](val1[[p]], val2[[p]]))
})
} else if (is.vector(val1) && is.vector(val2)) {
eqInd <- sapply(seq_len(length(val1)), function(x){
identical(val1[x], val2[x])
})
pt <- which(eqInd)
attr1[pt] <- val1[pt]
}
attr1
}
setMethod("graphIntersect", c("graphBAM", "graphBAM"),
function(x, y, nodeFun, edgeFun, ...){
nn <- intersect(nodes(x), nodes(y))
nnLen <- length(nn)
if(nnLen ==0) {
dr1 <- isDirected(x)
dr2 <- isDirected(y)
if(dr1 != dr2)
stop("'x' and 'y' should both be directed or undirected")
theMode <- if (dr1) "directed" else "undirected"
c0 <- character(0)
df <- data.frame(from = c0, to = c0, weight = numeric(0),
stringsAsFactors = FALSE)
ans <- graphBAM(df, edgemode = theMode)
return(ans)
}
sg1 <- if (nnLen == numNodes(x)) x else subGraph(nn, x)
sg2 <- if (nnLen == numNodes(y)) y else subGraph(nn, y)
if(missing(nodeFun))
nodeFun <- NULL
if(missing(edgeFun))
edgeFun <- NULL
edge_set <- .getEdgeIntersect(sg1@edgeSet, sg2@edgeSet)
ans <- .getBAMIntersect(sg1, sg2, edge_set, edgeFun)
ans@edgeData@defaults <-
.retEdgeIntersectDefaults(sg1@edgeData@defaults, sg2@edgeData@defaults)
ans@nodeData@defaults <- .retNodeIntersectDefaults(sg1, sg2)
ans@userAttrPos@nodePos <- .getIntNodeUserAttrPos(sg1, sg2)
ans@nodeData@data <- .nodeIntersect(sg1, sg2, ans, nodeFun)
ans
})
.getIntersectEdgeUserAttrPos <- function(edge_set) {
nms <- names(edge_set@edge_attrs)
structure(lapply(nms, function(){
edge_set@bit_vector
}), names = nms)
}
.retNodeUnionDefaults <- function(sg1, sg2) {
cmnAttrs <- intersect(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults))
unqAttrs <- unique(c(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults)))
singleAttrs <- unqAttrs[!( unqAttrs %in% cmnAttrs)]
cmn <- structure(lapply(cmnAttrs, function(x) {
if(identical(sg1@nodeData@defaults[[x]], sg2@nodeData@defaults[[x]])) sg1@nodeData@defaults[[x]] else NA
}), names = cmnAttrs)
sng <- structure(lapply(singleAttrs, function(x) {
if(x %in% names(sg1@nodeData@defaults))
sg1@nodeData@defaults[[x]]
else
sg2@nodeData@defaults[[x]]
}), names = singleAttrs)
c(cmn, sng)
}
.retNodeIntersectDefaults <- function(sg1, sg2) {
cmnAttrs <- intersect(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults))
structure(lapply(cmnAttrs, function(x) {
if(identical(sg1@nodeData@defaults[[x]], sg2@nodeData@defaults[[x]])) sg1@nodeData@defaults[[x]] else NA
}), names = cmnAttrs)
}
.retEdgeIntersectDefaults <- function(d1, d2) {
cmnAttrs <- intersect(names(d1), names(d2))
structure(lapply(cmnAttrs, function(x) {
if(identical(d1[[x]], d2[[x]])) d1[[x]] else NA
}), names = cmnAttrs)
}
.retEdgeUnionDefaults <- function(sg1, sg2) {
cmnAttrs <- intersect(names(sg1@edgeData@defaults), names(sg2@edgeData@defaults))
unqAttrs <- unique(c(names(sg1@edgeData@defaults), names(sg2@edgeData@defaults)))
singleAttrs <- unqAttrs[!( unqAttrs %in% cmnAttrs)]
cmn <- structure(lapply(cmnAttrs, function(x) {
if(identical(sg1@edgeData@defaults[[x]], sg2@edgeData@defaults[[x]])) sg1@edgeData@defaults[[x]] else NA
}), names = cmnAttrs)
sng <- structure(lapply(singleAttrs, function(x) {
if(x %in% names(sg1@edgeData@defaults))
sg1@edgeData@defaults[[x]]
else
sg2@edgeData@defaults[[x]]
}), names = singleAttrs)
c(cmn, sng)
}
.nodeIntersect <- function(sg1, sg2, ans, funList){
cmn <- intersect(names(sg1@nodeData@defaults), names(sg2@nodeData@defaults))
nattr <- structure(lapply(cmn, function(x) {
attr1 <- .getNodeAttrVec(sg1, x)
attr2 <- .getNodeAttrVec(sg2, x)
len <- length(attr1)
if(!is.null(funList) && (x %in% names(funList))) {
res <- sapply(seq_len(len), function(p) {
return(funList[[x]](attr1[[p]], attr2[[p]]))
})
} else if (is.vector(attr1) && is.vector(attr2)) {
indx <- which(sapply(seq_len(len), function(p){
identical(attr1[p], attr2[p])
}))
res <- rep(NA, len)
res[indx] <- attr1[indx]
}
res
res[bitToLogical(ans@userAttrPos@nodePos[[x]])]
}), names = cmn)
nattr
}
.scaleGraphBAM <- function(g, theNodes, edgemode) {
if(all(nodes(g) %in% theNodes) && length(nodes(g)) == length(theNodes))
return(g)
else {
ndsLen <- length(theNodes)
df <- extractFromTo(g)
bam <- graphBAM(df, nodes = theNodes, edgemode= edgemode,
ignore_dup_edges = FALSE)
bam@edgeSet@weights <- g@edgeSet@weights
bam@edgeSet@edge_attrs <- g@edgeSet@edge_attrs
bam@edgeData@defaults <- g@edgeData@defaults
nms <- names(g@nodeData@defaults)
for(i in nms){
origNds <- nodes(g)[(bitToLogical(g@userAttrPos@nodePos[[i]]))]
indx <- match(origNds, theNodes)
bt <- makebits(ndsLen)
bt <- setbitv(bt, indx, rep(1L, length(indx)))
bam@userAttrPos@nodePos[[i]] <- bt
bam@nodeData@data[[i]] <- g@nodeData@data[[i]]
}
bam@nodeData@defaults <- g@nodeData@defaults
nms <- names(g@userAttrPos@edgePos)
for(i in nms) {
ft <- .Call(graph_bitarray_rowColPos, g@userAttrPos@edgePos[[i]])
posBit <- .createZeroBitPos(ndsLen)
bam@userAttrPos@edgePos[[i]] <- setBitCell(posBit, ft[,"from"], ft[,"to"], rep(1L, nrow(ft)))
}
return(bam)
}
}
.bamUnion <- function(g1, g2, theNodes, nodeFun, edgeFun) {
dr1 <- isDirected(g1)
dr2 <- isDirected(g2)
if(dr1 != dr2)
stop("edges should both be directed or undirected")
theMode <- if (dr1 && dr2) "directed" else "undirected"
e1Attr <- names(g1@edgeSet@edge_attrs)
e2Attr <- names(g2@edgeSet@edge_attrs)
unionAttr <- unique(union(e1Attr, e2Attr))
if(!is.null(edgeFun)) {
fIndx <- names(edgeFun) %in% c(unionAttr, "weight")
if(!all(fIndx))
stop("attributes in 'edgeFun' not in edge attributes: ",
pasteq(names(edgeFun)[fIndx]))
}
bam1 <- .scaleGraphBAM(g1, theNodes, theMode)
bam2 <- .scaleGraphBAM(g2, theNodes, theMode)
bv <- bam1@edgeSet@bit_vector | bam2@edgeSet@bit_vector
attributes(bv) <- attributes(bam1@edgeSet@bit_vector)
attr(bv, "nbitset") <- ns <- .Call(graph_bitarray_sum, bv)
c0 <- character(0)
df <- data.frame(from = c0, to = c0, weight = numeric(0),
stringsAsFactors = TRUE)
edge_set <- .makeMDEdgeSet(es_name = 1, es =df,
is_directed = (theMode == "directed"),
nodes = theNodes, ignore_dup_edges = FALSE)
edge_set@bit_vector <- bv
ans <- new("graphBAM", edgeSet= edge_set, nodes =theNodes)
cmnBit <- bam1@edgeSet@bit_vector & bam2@edgeSet@bit_vector
attributes(cmnBit) <- attributes(bam1@edgeSet@bit_vector)
attr(cmnBit, "nbitset") <- .Call(graph_bitarray_sum, cmnBit)
fromOneBit <- bam1@edgeSet@bit_vector & (!cmnBit)
attributes(fromOneBit) <- attributes(bam1@edgeSet@bit_vector)
attr(fromOneBit, "nbitset") <- .Call(graph_bitarray_sum, fromOneBit)
fromTwoBit <- bam2@edgeSet@bit_vector & (!cmnBit)
attributes(fromTwoBit) <- attributes(bam2@edgeSet@bit_vector)
attr(fromTwoBit, "nbitset") <- .Call(graph_bitarray_sum, fromTwoBit)
attrType <- .Call(graph_bitarray_Union_Attrs, bv, cmnBit, fromOneBit,
fromTwoBit)
if(length(attrType$from) >0) {
edge_set@weights <- as.numeric(.getUnionWeights(attrType, bam1, bam2, edgeFun))
}
if(!is.null(unionAttr)) {
for(i in unionAttr) {
ans@userAttrPos@edgePos[[i]] <- edge_set@bit_vector
edge_set@edge_attrs[[i]] <- .getUnionAttrs(i, attrType, bam1, bam2, edgeFun)
}
}
ans@edgeSet <- edge_set
ans@nodeData@data <- .nodeUnion(g1, g2, nodeFun)
ans@userAttrPos@nodePos <- .getUnionNodeUserAttrPos(ans,bam1, bam2)
ans
}
setMethod("graphUnion", c("graphBAM", "graphBAM"),
function(x, y, nodeFun, edgeFun, ...) {
theNodes <- unique(c(nodes(x), nodes(y)))
nnLen <- length(theNodes)
if(nnLen ==0) {
dr1 <- isDirected(x)
dr2 <- isDirected(y)
if(dr1 != dr2)
stop("'x' and 'y' should both be directed or undirected")
theMode <- if (dr1) "directed" else "undirected"
c0 <- character(0)
df <- data.frame(from = c0, to = c0, weight = numeric(0),
stringsAsFactors = FALSE)
ans <- graphBAM(df, edgemode = theMode)
return(ans)
}
if(missing(nodeFun))
nodeFun <- NULL
if(missing(edgeFun))
edgeFun <- NULL
ans <- .bamUnion(x, y, theNodes, nodeFun, edgeFun)
ans@nodeData@defaults <- .retNodeUnionDefaults(x, y)
ans@edgeData@defaults <- .retEdgeUnionDefaults(x, y)
ans
})
.nodeUnion <- function(g1, g2, funList) {
xAttr <- names(g1@nodeData@defaults)
yAttr <- names(g2@nodeData@defaults)
if(!is.null(funList)) {
fIndx <- names(funList) %in% c(xAttr, yAttr)
if(!all(fIndx))
stop("attributes in 'nodeFun' not in node attributes: ",
pasteq(names(funList)[fIndx]))
}
ndX <- nodes(g1)
ndY <- nodes(g2)
ndAns <- unique(c(ndX, ndY))
unionAttrs <- union(xAttr, yAttr)
commonAttrs <- intersect(xAttr,yAttr)
singleAttrs <- unionAttrs[!unionAttrs %in% commonAttrs]
cmnNds <- intersect(ndX, ndY)
fxNds <- ndX[!ndX %in% cmnNds]
fyNds <- ndY[!ndY %in% cmnNds]
### deal with single attrs
n1 <- sapply(singleAttrs, function(k){
if(k %in% xAttr){
att <- .getNodeAttrVec(g1, k)
} else if(k %in% yAttr){
att <- .getNodeAttrVec(g2, k)
}
list(att)
})
n2 <- sapply(commonAttrs, function(k) {
att <- rep(NA, length(ndAns))
##from X
indx <- match(fxNds, ndAns)
attr1 <- .getNodeAttrVec(g1, k)
attr2 <- .getNodeAttrVec(g2, k)
att[indx] <- attr1[match(fxNds,ndX)]
##from Y
indx <- match(fyNds, ndAns)
att[indx] <- attr2[match(fyNds,ndY)]
if(!is.null(funList) && (k %in% names(funList))) {
tmp <- sapply(cmnNds, function(p){
dX <- match(p, ndX)
dY <- match(p, ndY)
funList[[k]](attr1[[dX]], attr2[[dY]])
}, USE.NAMES = FALSE)
indx <- match(cmnNds, ndAns)
att[indx] <- tmp
} else if (is.vector(attr1) && is.vector(attr2)){
tmp <- sapply(cmnNds, function(p){
dX <- match(p, ndX)
dY <- match(p, ndY)
identical(attr1[[dX]], attr2[[dY]])
}, USE.NAMES = FALSE)
indx <- match(cmnNds[tmp], ndAns)
att[indx] <- attr1[match(cmnNds[tmp], ndX)]
}
list(att)
})
c(n1,n2)
}
setMethod("nodeDataDefaults",
signature(self="graphBAM", attr="missing"),
function(self, attr){
attrDefaults(self@nodeData)
})
setMethod("nodeDataDefaults",
signature(self="graphBAM", attr="character"),
function(self, attr){
attrDefaults(self@nodeData, attr)
})
setReplaceMethod("nodeDataDefaults",
signature(self="graphBAM", attr="missing", value="list"),
function(self, attr, value) {
attrDefaults(self@nodeData) <- value
nmsNds <- names(self@nodeData@defaults)
nmsAttr <- names(self@userAttrPos@nodePos)
ndsLbls <- nmsNds[ !(nmsNds %in% nmsAttr)]
if(length(ndsLbls)) {
ndsLen <- length(nodes(self))
bt <- makebits(ndsLen)
}
for(i in ndsLbls) {
self@userAttrPos@nodePos[[i]] <- bt
}
self
})
setReplaceMethod("nodeDataDefaults",
signature(self="graphBAM", attr="character", value="ANY"),
function(self, attr, value) {
attrDefaults(self@nodeData, attr) <- value
ndsLen <- length(nodes(self))
if(! (attr %in% names(self@userAttrPos@nodePos))){
bt <- makebits(ndsLen)
self@userAttrPos@nodePos[[attr]] <- bt
}
self
})
## Node data replacement methods
.getNodeAttrOrder <- function(x, indx) {
len <- attr(x, "bitlen")
nset <- attr(x, "nbitset")
if (is.null(len)) len <- length(x) * 8L
k <- p <- 1
setIndx = 1
attrIndx = 1
k2<- k3 <- k1 <- 1
nval = vector(length(indx), mode ="integer")
npos <- nval
fpos = vector(max(c(nset, length(indx))), mode ="integer")
fval = vector(max(c(nset, length(indx))), mode ="integer")
mm <- length(indx)
for( i in seq_len(len)) {
bt <- testbit(x, i)
intIndx <- indx[attrIndx]
if(bt) {
if(intIndx == i) {
nval[k2] = attrIndx
npos[k2] = k3
k2 <- k2 + 1
k3 <- k3 + 1
if(attrIndx < mm)
attrIndx = attrIndx +1
}
if(intIndx != i){
fpos[k1] <- setIndx
fval[k1] <- k1
k1 <- k1+1
k3 <- k3+ 1
}
setIndx <- setIndx +1
}
}
length(fpos) <- k1-1
length(fval) <- k1-1
attributes(fval) <- list("origPos" = fpos)
attributes(nval) <- list("newPos" = npos)
list( origVal = fval, newVal = nval)
}
setReplaceMethod("nodeData",
signature(self = "graphBAM", n="character", attr="character", value="ANY"),
function(self, n, attr, value) {
.nodeDataReplaceNodeGiven(self, n ,attr, value)
})
setReplaceMethod("nodeData",
signature(self = "graphBAM", n="missing", attr="character", value="ANY"),
function(self, n, attr, value) {
.nodeDataReplaceNodeMissing(self, attr, value)
})
.getNodeAttrPos <- function(x, indx) {
bt <- bitToLogical(x)
leftPos <- which(bt[indx])
cs <- cumsum(bt)
k <- indx[bt[indx]]
rightPos <- cs[k ]
list(leftPos= leftPos, rightPos = rightPos)
}
## Node data accces methods
setMethod("nodeData",
signature(self = "graphBAM", n = "character", attr = "character"),
function(self, n, attr) {
.nodeDataRetrieve(self, n, attr)
})
setMethod("nodeData",
signature(self = "graphBAM", n = "missing", attr = "character"),
function(self, n, attr) {
if(length(attr) != 1L)
stop("'attr' must specify a single attribute name")
nds <- nodes(self)
nodeData(self, n= nds, attr= attr)
})
setMethod("nodeData",
signature(self = "graphBAM", n = "character", attr = "missing"),
function(self, n, attr) {
nds <- nodes(self)
.verifyNodes(n ,nds)
nms <- names(self@nodeData@defaults)
structure(lapply(nms, function(x) {
nodeData(self, n, x)
}), names = nms)
})
setMethod("nodeData",
signature(self = "graphBAM", n = "missing", attr = "missing"),
function(self, n, attr) {
nds <- nodes(self)
nms <- names(self@nodeData@defaults)
structure(lapply(nms, function(x) {
nodeData(self, nds, x)
}), names = nms)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.