1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
# Randomly perturb a supplied network.
# <perturb="functions"> perturbs the functions associated with the genes directly.
# <perturb="states"> perturbs a maximum of <numStates> states
# in the transition table resulting from the functions.
# <method="bitflip"> randomly flips up to <maxNumBits> in the functions or states.
# <method="shuffle"> randomly permutes the bits in the functions or states.
# If <simplify> is set, the perturbed network is simplified to remove irrelevant input functions.
# If <excludeFixed> is set, fixed genes are excluded from the perturbations and stay as they are.
perturbNetwork <- function(network,perturb=c("functions","transitions"),method=c("bitflip","shuffle"),
simplify=(perturb[1]!="functions"),readableFunctions=FALSE,excludeFixed=TRUE,
maxNumBits=1,numStates=max(1,2^length(network$genes)/100))
{
stopifnot(inherits(network,"BooleanNetwork") | inherits(network,"ProbabilisticBooleanNetwork"))
fixedGenes <- which(network$fixed != -1)
if (length(perturb) == 1 && perturb == "states")
{
warning("perturb=\"states\" is deprecated. Use perturb=\"transitions\" instead!")
perturb <- "transitions"
}
if (inherits(network,"BooleanNetwork"))
# deterministic network
{
switch(match.arg(perturb,c("functions","transitions")),
functions=
switch(match.arg(method,c("bitflip","shuffle")),
bitflip =
{
# choose the function to be perturbed
if (length(fixedGenes) > 0 & excludeFixed)
functionIdx <- sample((seq_along(network$interactions))[-fixedGenes],size=1)
else
functionIdx <- sample(seq_along(network$interactions),size=1)
# choose the indices of the truth table to be flipped
flipIndices <- sample(seq_along(network$interactions[[functionIdx]]$func),
size=runif(n=1,min=1,
max=min(maxNumBits,
length(network$interactions[[functionIdx]]$func))),
replace=FALSE)
# flip the bits
network$interactions[[functionIdx]]$func[flipIndices] <-
as.integer(!network$interactions[[functionIdx]]$func[flipIndices])
network$interactions[[functionIdx]]$expression <-
getInteractionString(readableFunctions,
network$interactions[[functionIdx]]$func,
network$genes[network$interactions[[functionIdx]]$input])
},
shuffle=
{
# choose the function to be perturbed
if (length(fixedGenes) > 0 & excludeFixed)
functionIdx <- sample((seq_along(network$interactions))[-fixedGenes],size=1)
else
functionIdx <- sample(seq_along(network$interactions),size=1)
# draw a random permutation of bit positions
flipIndices <- sample(seq_along(network$interactions[[functionIdx]]$func),
size=length(network$interactions[[functionIdx]]$func),
replace=FALSE)
# permute the bits
network$interactions[[functionIdx]]$func <-
network$interactions[[functionIdx]]$func[flipIndices]
network$interactions[[functionIdx]]$expression <-
getInteractionString(readableFunctions,
network$interactions[[functionIdx]]$func,
network$genes[network$interactions[[functionIdx]]$input])
},
stop("'method' must be one of \"bitflip\",\"shuffle\"")),
transitions =
{
# turn off gene fixing - otherwise reverse-engineering of the transition table is not possible
oldFixed <- network$fixed
network$fixed <- rep(-1,length(network$genes))
names(network$fixed) <- network$genes
# calculate transition table
table <- t(sapply(getAttractors(network)$stateInfo$table,dec2bin,length(network$genes)))
# determine the states to be perturbed
statesToChange <- sample(seq_len(nrow(table)),min(numStates,nrow(table)),replace=FALSE)
lapply(statesToChange,function(state)
{
# choose the indices of the states that are allowed to be changed
flipIndices <- seq_along(network$genes)
if (length(fixedGenes) > 0 & excludeFixed)
flipIndices <- flipIndices[-fixedGenes]
switch(match.arg(method,c("bitflip","shuffle")),
bitflip =
{
# choose the actual indices to be changed
flipIndex <- sample(flipIndices,
size=runif(n=1,min=1,
max=min(maxNumBits,
length(flipIndices))),
replace=FALSE)
# flip the bits at these positions
table[state,flipIndex] <<-
as.integer(!table[state,flipIndex])
},
shuffle =
{
# determine a permutation of the bit indices
flipIndex <- sample(flipIndices,
size=length(flipIndices),
replace=FALSE)
# permute the state
table[state,] <<-
as.integer(table[state,flipIndex])
},
stop("'method' must be one of \"bitflip\",\"shuffle\"")
)
NULL})
# restore network by assigning the columns of the state table to the corresponding genes
network$interactions <- apply(table,2,function(gene)
{
input = seq_along(network$genes)
# encoding is reversed in the transition table
input <- input[length(input):1]
list(input=input,
func=gene,
expression= getInteractionString(readableFunctions,
gene,
network$genes[input]))
})
# reactivate fixed genes
network$fixed <- oldFixed
},
stop("'perturb' must be one of \"functions\",\"transitions\""))
}
else
# probabilistic network
{
if (match.arg(perturb) != "functions")
stop("In probabilistic Boolean networks, only perturb=functions is allowed!")
switch(match.arg(method,c("bitflip","shuffle")),
bitflip =
{
# choose the gene and the function to be perturbed
if (length(fixedGenes) > 0 & excludeFixed)
geneIdx <- sample((seq_along(network$interactions))[-fixedGenes],size=1)
else
geneIdx <- sample(seq_along(network$interactions),size=1)
functionIdx <- sample(seq_along(network$interactions[[geneIdx]]),size=1)
# choose the indices of the truth table to be flipped
flipIndices <- sample(seq_along(network$interactions[[geneIdx]][[functionIdx]]$func),
size=runif(n=1,min=1,
max=min(maxNumBits,
length(network$interactions[[geneIdx]][[functionIdx]]$func))),
replace=FALSE)
# flip the bits
network$interactions[[geneIdx]][[functionIdx]]$func[flipIndices] <-
as.integer(!network$interactions[[geneIdx]][[functionIdx]]$func[flipIndices])
network$interactions[[geneIdx]][[functionIdx]]$expression <-
getInteractionString(readableFunctions,
network$interactions[[geneIdx]][[functionIdx]]$func,
network$genes[network$interactions[[geneIdx]][[functionIdx]]$input])
},
shuffle=
{
# choose the function to be perturbed
if (length(fixedGenes) > 0 & excludeFixed)
geneIdx <- sample((seq_along(network$interactions))[-fixedGenes],size=1)
else
geneIdx <- sample(seq_along(network$interactions),size=1)
functionIdx <- sample(seq_along(network$interactions[[geneIdx]]),size=1)
# draw a random permutation of bit positions
flipIndices <- sample(seq_along(network$interactions[[geneIdx]][[functionIdx]]$func),
size=length(network$interactions[[geneIdx]][[functionIdx]]$func),
replace=FALSE)
# permute the bits
network$interactions[[geneIdx]][[functionIdx]]$func <-
network$interactions[[geneIdx]][[functionIdx]]$func[flipIndices]
network$interactions[[geneIdx]][[functionIdx]]$expression <-
getInteractionString(readableFunctions,
network$interactions[[geneIdx]][[functionIdx]]$func,
network$genes[network$interactions[[geneIdx]][[functionIdx]]$input])
},
stop("'method' must be one of \"bitflip\",\"shuffle\""))
}
# simplify the network if necessary
if (simplify)
network <- simplifyNetwork(network,readableFunctions)
return(network)
}
|