Nothing
#' @title Verbose cat
#'
#' @description
#' This function is a simple wrapper for cat with a Boolean value for turning it on/off.
#'
#' @param string character vector. String intended to be printed.
#' @param bool logical. Specify whether to print the string to stout or not.+
vcat = function(string, bool)
{
if(bool)
{
cat(string)
}
invisible()
}
#' @title Check if containing AND terms
#'
#' @description
#' This function checks if a particular Boolean model contains AND terms.
#'
#' @param bmodel BoolModel object.
check_and = function(bmodel)
{
and_bool = F
if(any(grepl('&', bmodel@rule_act)))
{
and_bool = T
} else if(any(grepl('&', bmodel@rule_inh)))
{
and_bool = T
}
return(and_bool)
}
#' @title Extract Boolean terms
#'
#' @description
#' This function extracts the terms within a Boolean rule, using OR as the separator. Bracketed variables are counted as one term.
#'
#' @param brule character vector. It should be either an activating or inhibiting rule for a target gene.
extract_term = function(brule)
{
if(brule!='0') #account for cases with empty rule.
{
#Strip outermost brackets.
brule = gsub('^[(](.+)[)]$', '\\1', brule)
term = strsplit(brule, '[|]')[[1]]
term = gsub('^[(](.+)[)]$', '\\1', term)
} else
{
term = '0'
}
return(term)
}
#' @title Check for matching terms
#'
#' @description
#' This function checks if the first term is found within a vector of terms. Return a logical value.
#' It is smarter than simple string matching, e.g. match_term(v1s&v2s, v2s&v1s) == T, match_term(v1s, v1s&v2s) == T, match_term(v1s&v2s, v1s) == T.
#'
#' @param t1 character vector of length 1 or more. It should be a vector of gene variable.
#' @param t2 character vector of length 1 or more. It should be a vector of gene variables.
#' @param mode character. Indicates the mode of action. Options: 'logic', 'unique'. Default to 'logic'.
match_term = function(t1, t2, mode='logic')
{
if(t1[1] != '0')
{
t1 = unlist(strsplit(t1, '&')) #this will split up terms with &.
#Check if t1 is present in t2.
#Note: if t1='v1s', this will match 'v1s', 'v2s&v1s'.
if(length(t2) > 1)
{
check_mat = sapply(t1, function(x) grepl(x, t2))
} else
{
check_mat = t(matrix(sapply(t1, function(x) grepl(x, t2)))) #matrix() is necessary when t2 has length 1.
}
if(mode == 'logic')
{
check_ind = which(rowSums(check_mat) > 0)
if(length(check_ind) == 0)
{
match = FALSE
} else
{
match = TRUE
}
return(match)
} else if(mode == 'unique')
{
check_ind = which(rowSums(check_mat) == 0)
return(t2[check_ind])
} else
{
stop('Error in specifying match_term() mode.')
}
} else if(t1[1] == '0')
{
if(mode == 'logic')
{
return(FALSE)
} else if(mode == 'unique')
{
return(t2)
} else
{
stop('Error in specifying match_term() mode.')
}
}
}
#' @title Pick a random minimum value
#'
#' @description
#' This function locates the minimum value in a vector (similar to which.min), however it will randomly break ties when there are multiple minimum values.
#'
#' @param x numeric vector.
#' @param favour_first logical. If this is TRUE, and the first value in the vector supplies is one of the min, the index for the first value will always be returned.
which.random.min = function(x, favour_first=F)
{
id = which(x == min(x)) #get indices of all minimum values.
# If the minimum value appear multiple times pick one index at random, otherwise just return its position in the vector
# Exception occurs if the initial model (at position 1) also has the minimum value, then the initial model is favoured.
if(length(id) > 1 & 1 %in% id & favour_first==T)
{
id = 1
} else if(length(id) > 1) #for all other cases with multiple minimum values, pick a random one.
{
id = sample(id, 1)
} else if(length(id) == 1) #if there is only single min value, return it.
{
id = id
}
return(id)
}
# #' @title Filter a Boolean model
# #'
# #' @description
# #' This function filters a Boolean model to retain only overlapping genes.
# #'
# #' @param x BoolModel.
# #' @param y character vector. Overlapping genes.
# filter_bmodel = function(x, y)
# {
# stopifnot(class(x)== 'BoolModel')
#
# if(uniq_bool)
# {
# return(unique(x[,colnames(x) %in% y, drop=F]))
# } else
# {
# return(x[,colnames(x) %in% y, drop=F])
# }
# }
#' @title Filter columns of df in a list
#'
#' @description
#' This function filters columns of multiple df in a list, when compared using a vector. Use through lapply().
#'
#' @param x data frame. It should be a list element if used from lapply.
#' @param y character vector. It should contains gene names found in the colnames of the data frame.
#' @param uniq_bool logical. Whether to return unique rows only.
filter_dflist = function(x, y, uniq_bool=T)
{
stopifnot(class(x)== 'data.frame' | class(x)== 'matrix')
if(uniq_bool)
{
return(unique(x[,colnames(x) %in% y, drop=F]))
} else
{
return(x[,colnames(x) %in% y, drop=F])
}
}
#' @title Calculate distance between Boolean models
#'
#' @description
#' This method takes in two models and calculate the distance between them. The value return indicate the number of steps between the two models.
#'
#' @param x S4 BoolModel object. Test model.
#' @param y S4 BoolModel object. Reference model.
#'
#' @export
model_dist = function(x, y)
{
set_diff = unlist(model_setdiff(x, y))
#Calculate total dist.
t_dist = length(set_diff)
#Return results.
return(t_dist)
}
#' @title Find the set difference between two Boolean models
#'
#' @description
#' This method takes in two models and find the set difference between them. Return a vector with the set difference.
#'
#' @param x S4 BoolModel object. Test model.
#' @param y S4 BoolModel object. Reference model.
#' @param directed logical. If TRUE, return the difference in terms with respect to x.
#'
#' @export
model_setdiff = function(x, y, directed=F)
{
stopifnot(length(x@target) == length(y@target))
stopifnot(get_encodings(x)[[1]]==get_encodings(y)[[1]])
ind = get_encodings(x)
x1 = compress_bmodel(x, ind)
x2 = compress_bmodel(y, ind)
ind = ind[[1]]
#Pick which model has more terms, and which has less.
more_ind = which.max(c(length(x1), length(x2)))
less_ind = ifelse(more_ind==1, 2, 1)
more_x = list(x1, x2)[[more_ind]]
less_x = list(x1, x2)[[less_ind]]
#Remove empty terms.
more_x = more_x[more_x%%1!=0]
less_x = less_x[less_x%%1!=0]
#Remove 0 and !0.
#Find the encodings for 0 and !0.
zero_enc = as.numeric(paste('0.', ind[which(names(ind)=='0')], sep=''))
notzero_enc = as.numeric(paste('0.', ind[which(names(ind)=='!0')], sep=''))
#Remove them.
more_x = more_x[round(more_x-round(more_x), 4)!=zero_enc]
more_x = more_x[round(more_x-round(more_x), 4)!=notzero_enc]
less_x = less_x[round(less_x-round(less_x), 4)!=zero_enc]
less_x = less_x[round(less_x-round(less_x), 4)!=notzero_enc]
#Check for set difference.
more_bool = sapply(more_x, function(x) !(x %in% less_x))
less_bool = sapply(less_x, function(x) !(x %in% more_x))
more_diff = more_x[more_bool]
less_diff = less_x[less_bool]
more_vec = c()
if(length(more_diff)>0)
{
gene = round(more_diff)
rule = gsub('^[0-9]+[.]', '', gsub(' ', '', format(more_diff, nsmall=4)))
gene = x@target[gene]
rule = unname(sapply(rule, function(x) names(which(ind==x))[1]))
more_vec = rule
names(more_vec) = gene
}
less_vec = c()
if(length(less_diff)>0)
{
gene = round(less_diff)
rule = gsub('^[0-9]+[.]', '', gsub(' ', '', format(less_diff, nsmall=4)))
gene = x@target[gene]
rule = unname(sapply(rule, function(x) names(which(ind==x))[1]))
less_vec = rule
names(less_vec) = gene
}
#Handle step difference that includes changing to and from AND terms.
if(length(more_vec) != 0 & length(less_vec) != 0)
{
for(i in 1:length(more_vec))
{
for(j in 1:length(less_vec))
{
if(names(more_vec[i])==names(less_vec[j]))
{
if(grepl('!', more_vec[i]) & grepl('!', less_vec[j])) #for both inh terms. do not cross compare act and inh terms.
{
#Split & terms if present.
mvec = unlist(strsplit(more_vec[i], '&'))
lvec = unlist(strsplit(less_vec[j], '&'))
#Removes !.
mvec = gsub('!', '', mvec)
lvec = gsub('!', '', lvec)
#Check for presence of &.
mand_bool = ifelse(grepl('&', more_vec[i]), T, F)
land_bool = ifelse(grepl('&', less_vec[j]), T, F)
mbool = mvec %in% lvec
lbool = lvec %in% mvec
#assign NA if there is no term remaining.
if(length(mvec[!mbool])!=0)
{
if(!is.na(mvec[!mbool][1]))
{
more_vec[i] = paste(mvec[!mbool], collapse='&')
}
} else
{
more_vec[i] = NA
}
if(length(lvec[!lbool])!=0)
{
if(!is.na(lvec[!lbool][1]))
{
less_vec[j] = paste(lvec[!lbool], collapse='&')
}
} else
{
less_vec[j] = NA
}
#if this involves AND term, adds & indicator to term name.
if(mand_bool & !is.na(more_vec[i]) & !grepl('&', more_vec[i]))
{
more_vec[i] = paste('&', more_vec[i], sep='')
}
if(land_bool & !is.na(less_vec[j]) & !grepl('&', less_vec[j]))
{
less_vec[j] = paste('&', less_vec[j], sep='')
}
#Add the ! back to the terms.
if(!is.na(more_vec[i]))
{
if(grepl('^&', more_vec[i]))
{
more_vec[i] = gsub('(^[&])(.+)', '\\1!\\2', more_vec[i])
} else
{
more_vec[i] = paste('!', more_vec[i], sep='')
}
}
if(!is.na(less_vec[j]))
{
if(grepl('^&', less_vec[j]))
{
less_vec[j] = gsub('(^[&])(.+)', '\\1!\\2', less_vec[j])
} else
{
less_vec[j] = paste('!', less_vec[j], sep='')
}
}
} else if(!grepl('!', more_vec[i]) & !grepl('!', less_vec[j])) #for both act terms. do not cross compare act and inh terms.
{
#Split & terms if present.
mvec = unlist(strsplit(more_vec[i], '&'))
lvec = unlist(strsplit(less_vec[j], '&'))
#Check for presence of &.
mand_bool = ifelse(grepl('&', more_vec[i]), T, F)
land_bool = ifelse(grepl('&', less_vec[j]), T, F)
mbool = mvec %in% lvec
lbool = lvec %in% mvec
#assign NA if there is no term remaining.
if(length(mvec[!mbool])!=0)
{
if(!is.na(mvec[!mbool][1]))
{
more_vec[i] = paste(mvec[!mbool], collapse='&')
}
} else
{
more_vec[i] = NA
}
if(length(lvec[!lbool])!=0)
{
if(!is.na(lvec[!lbool][1]))
{
less_vec[j] = paste(lvec[!lbool], collapse='&')
}
} else
{
less_vec[j] = NA
}
#if this involves AND term, adds & indicator to term name.
if(mand_bool & !is.na(more_vec[i]) & !grepl('&', more_vec[i]))
{
more_vec[i] = paste('&', more_vec[i], sep='')
}
if(land_bool & !is.na(less_vec[j]) & !grepl('&', less_vec[j]))
{
less_vec[j] = paste('&', less_vec[j], sep='')
}
}
}
}
}
}
#Remove NAs.
if(!is.null(more_vec))
{
more_vec = more_vec[!is.na(more_vec)]
}
if(!is.null(less_vec))
{
less_vec = less_vec[!is.na(less_vec)]
}
#If there are any AND term remaining here, they should be separated as they count as 2 steps.
if(length(more_vec)!=0)
{
for(i in 1:length(more_vec))
{
if(grepl('.+&.+', more_vec[i]))
{
tmp_entry = unlist(strsplit(more_vec[i], '&'), use.names=F)
names(tmp_entry) = rep(names(more_vec[i]), length(tmp_entry))
more_vec = c(more_vec, tmp_entry)
more_vec = more_vec[-i]
}
}
}
if(length(less_vec)!=0)
{
for(i in 1:length(less_vec))
{
if(grepl('.+&.+', less_vec[i]))
{
tmp_entry = unlist(strsplit(less_vec[i], '&'), use.names=F)
names(tmp_entry) = rep(names(less_vec[i]), length(tmp_entry))
less_vec = c(less_vec, tmp_entry)
less_vec = less_vec[-i]
}
}
}
comb_vec = c(more_vec, less_vec)
#Replace the gene names back into update functions.
for(i in 1:length(x@target_var))
{
comb_vec = gsub(x@target_var[i], x@target[i], comb_vec)
}
stopifnot(all(!grepl('v[0-9]+s', unlist(strsplit(comb_vec, '&'))) |
!grepl('^0$', unlist(strsplit(comb_vec, '&'))))) #check if all gene name conversions is successful.
#Return results.
if(directed)
{
return(list(more=more_vec, less=less_vec))
} else
{
return(list(comb_vec))
}
}
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.