library(shiny)
library(shinydashboard)
library(shinyjs)
library(DT)
library(V8)
library(igraph)
library(rcytoscapejs)
load('GDinfo.RData')
download_data = function(filename, species){
githubURL = paste("https://github.com/GScluster/data/raw/master/",species,"/",filename, sep='')
download.file(url = githubURL,filename)
}
check_data = function(species){
species = tolower(species)
nowdir = getwd()
nowTOv = getOption('timeout')
options(timeout=1800)
data_dir = file.path('data',species, fsep = '/')
dir.create('data')
if(!dir.exists(data_dir)){dir.create(data_dir)}
setwd(data_dir)
filename_footer = '.RData'
filenames= c('li1','li2','li3','li4','li5','li6','li7','ensg_ent','ent_sym','string')
# when species == 'ecoli / yeast'
if(species=='ecoli' | species=='yeast' || species =='arabidopsis'){
filenames= c('li1','li2','li3','li4','li5','li6','li7','ent_sym','string')
}
progress_download = shiny::Progress$new()
on.exit(progress_download$close())
progress_download$set(message='Download Datas', value = 0)
for(i in filenames){
filename = paste(i,filename_footer,sep='')
progress_download$inc(1/length(filenames), detail = i)
if(!file.exists(filename)){ download_data(filename, species) }
}
progress_download$close()
progress_load = shiny::Progress$new()
on.exit(progress_load$close())
progress_load$set(message='Loading Datas', value = 0)
for(i in dir()){
load(i, envir = .GlobalEnv)
progress_load$inc(1/length(filenames), detail = i)
}
options(timeout = nowTOv)
setwd(nowdir)
}
tablestring = function(x, lx, cv, cls){
temp = ""
for(i in 1:floor(lx/cv)){ temp = paste(temp, paste(x[(1:cv+cv*(i-1))], collapse = cls), '\n', sep = '') }
if(i*cv+1 <= lx){
temp = paste(temp, paste(x[(i*cv+1):lx], collapse = cls), collapse = '', sep = '')}
return(temp)
}
ovl = function(a, b){length(intersect(a, b))/min(length(a), length(b))}
get_dist_O = function(gsl){
d = length(gsl)
gsl_dist = matrix(0,d,d)
Distance_O = function(gs1,gs2){ 1-ovl(gs1,gs2) }
for(i in 1:d){
for(j in 1:d){
if(i>j){gsl_dist[i,j] = gsl_dist[j,i]; next}
if(i==j){gsl_dist[i,j] = 0.001; next}
gsl_dist[i,j] = Distance_O(gsl[[i]],gsl[[j]])
}
}
return(gsl_dist);
}
build_clust_info = function(clusts, GS, GM, GQ){
df = data.frame(matrix(ncol = 4, nrow = 0))
colnames(df) = c("Geneset Name","Geneset Qvalue", "Geneset member", 'Cluster')
global_gsm = list()
gs_cnt = 1
nodes = c()
for(i in 1:length(clusts)){
this_clust = clusts[[i]]
for(j in 1:length(this_clust)){
gsn = GS[this_clust[j]]
lgsn = nchar(gsn)
# if long: add \n
if(lgsn>30){ gsn = tablestring(x = strsplit(gsn,'')[[1]],lx=lgsn,cv=30, cls = '') }
gsm = GM[[this_clust[j]]]
# if long: add \n
if(length(gsm)>20){ gsm = tablestring(x = gsm, lx = length(gsm), cv = 20, cls=',') }
else{ gsm = paste(gsm,collapse = ',') }
global_gsm[[gs_cnt]] = gsm;
gs_cnt = gs_cnt + 1
gsq = GQ[this_clust[j]]
df = rbind(df,cbind(gsn, round(gsq,5), gsm, i))
}
}
assign('global_gsm',global_gsm, envir = .GlobalEnv)
df[,1] = as.character(df[,1])
df[,2] = as.numeric(as.character(df[,2]))
return(df)
}
jsCode = 'shinyjs.pageCol = function(i){color = i[1];i = i[0];cy.nodes("#".concat(i)).style("background-color",color)};
shinyjs.clearCol = function(i){cy.nodes("#".concat(i)).style("background-color","#888888")};
shinyjs.remove_cy = function(){cy.$().remove()};
shinyjs.geneColQ1 = function(i){cy.nodes("#".concat(i)).style("background-color","#FBCDCD")};
shinyjs.geneColQ2 = function(i){cy.nodes("#".concat(i)).style("background-color","#F89A9A")};
shinyjs.geneColQ3 = function(i){cy.nodes("#".concat(i)).style("background-color","#F46767")};
shinyjs.geneColQ4 = function(i){cy.nodes("#".concat(i)).style("background-color","#F03434")};
shinyjs.download = function(){download()};
shinyjs.layout_as_cose = function(){layout_as_cose()};
shinyjs.layout_as_cola = function(){layout_as_cola()};
shinyjs.layout_as_circle = function(){layout_as_circle()};
shinyjs.fold_sidebar = function(){$("body").addClass("sidebar-collapse")};
shinyjs.open_sidebar = function(){$("body").removeClass("sidebar-collapse")};
shinyjs.define_cy = function(){cy = cytoscape()};
shinyjs.fit_node = function(id){
cy.zoom(0.7);
curpos = cy.pan();
curpos_x = curpos.x;
curpos_y = curpos.y;
nodpos = cy.nodes("#"+id).renderedPosition();
nodpos_x = nodpos.x;
nodpos_y = nodpos.y;
cy.pan({x: curpos_x+ cy.width()/2 - nodpos_x, y : curpos_y + cy.height()/2 - nodpos_y});
}
shinyjs.draw_edge = function(v){
v = v[0];
var source = v[0];
var target = v[1];
var w = v[2];
cy.edges(\'[source="\' + source + \'"][target="\' + target + \'"]\').css("width",w)
}
shinyjs.rename = function(name_before, name_after){
cy.nodes(paste0("#",name_before)).data("name",name_after)
}
'
node_rename = function(name_before, name_after){
js$rename(name_before, name_after)
}
UI_header = function(){
dashboardHeader( title = 'GScluster', titleWidth = 250)
}
UI_sidebar = function(){
dashboardSidebar(
width = 250,
sidebarMenu(
id='tabs',
menuItem(text = "Geneset Network", tabName = "Genesets", icon = icon("share-alt")),
menuItem(text = "Cluster info", tabName = "Clusters", icon = icon("list-ul")),
menuItem(text = "Downloads", tabName = "Downloads", icon = icon("download")),
menuItem(text = "MANUAL", tabName = "README", icon = icon("info-circle")),
hidden(actionButton("AB1","AB1"),actionButton("AB2","AB2"))
)
)
}
InputBox = function(){
div(
id = 'Input_box',
fileInput(inputId = "INPUT_GENESET_FILE", label = "Geneset: ", accept = 'text/plain'),
numericInput(inputId = 'GENESET_CUTOFF', label = "Geneset Cutoff: ", min = 0, max = 1, value = 0.25, step = 0.01),
fileInput(inputId = "INPUT_GENESCORE_FILE", label = "Gene score file : (Optional) ", accept = 'text/plain'),
numericInput(inputId = 'GENESCORE_CUTOFF', label = "Gene score Cutoff: ", min = 0, max = 1, value = 0.05, step = 0.01),
selectInput(inputId = 'INPUT_SPECIES', label='Choose Species', choices = c('Human', 'Arabidopsis', 'Celegans','Ecoli','Fly','Mouse','Rat','Yeast','Zebrafish'), selected = 'Human'),
checkboxInput(inputId = 'WORKING_GENE', label = 'Sig Gene only', value = FALSE),
actionButton(inputId = 'RUN', label = 'RUN'),
actionButton(inputId = 'DEMO',label = 'TRY DEMO')
)
}
NodeSearch = function(){
fluidRow( style = {'position:absolute;margin-left:7%;z-index:999;width:15%;'},selectizeInput('FIT',label = 'Gene-set search', choices = NULL) )
}
NodeSearchSubmit = function(){
fluidRow( style={'position:absolute;margin-left:25%;margin-top:24px;z-index:999'},actionButton('ACTIVATEFIT',"Search"))
}
ClusterLegend = function(){
uiOutput(
style={'position:absolute;top:6em;left:6em;z-index:999'},
outputId='legend'
)
}
build_Disease_Table = function(genes){
res = GDinfo[genes]
Ds = c()
for(i in 1:length(res)){ Ds = c(Ds,names(res[[i]])) }
sigDs = names(which(table(Ds)>1))
getV = function(res,sigD){
v = c()
for(i in 1:length(res)){ if(sigD %in% names(res[[i]])) { v = c(v,names(res)[i]) } }
return(c(paste(v,collapse=', '), length(v)))
}
df = data.frame(matrix(ncol = 3, nrow = 0))
for(i in 1:length(sigDs)){
v = getV(res, sigDs[i])
v = cbind(sigDs[i], v[2],v[1] )
df = rbind(df, v)
}
colnames(df) = c("Disease", "Count", "Genes")
dtres = datatable(
df,
filter = 'top',
options = list(
lengthChange = TRUE,
pageLength = 10,
columnDefs = list(list(targets = c(2), searchable = FALSE)),
scrollX = '350px',#TRUE,
scrollY = '300px',#TRUE,
autoWidth = TRUE,
order = list(2,'desc')
),
colnames = c("Disease", "Count", "Genes"),
selection = 'none'
)
return(dtres)
}
Download_SVG = function(){
fluidRow(
style={'position:absolute; margin-left:53%;z-index:999'},
actionButton(inputId='download_button',label='Download Graph', onclick='shinyjs.download()')
)
}
Download_SUBPPI = function(){
fluidRow(
style={'position:absolute; margin-left:66%;z-index:999'},
downloadButton(outputId = 'subPPI',label= 'Download PPI', style='display:none')
)
}
LayoutButton = function(){
fluidRow(
style={'position:absolute; margin-left:40%;z-index:999'},
verticalLayout(
actionButton(inputId = 'Layout_button', label = 'Layout Options', onclick='$("#DISPLAY_OPTIONS").toggle("slow","swing")'),
fluidRow(
id='DISPLAY_OPTIONS',
style='display:none;margin-top:10px;margin-left:0px;',
actionButton(inputId='circle_button',label='Circle', onclick= 'layout_as_circle()'),
actionButton(inputId='cola_button',label='Cola', onclick='layout_as_cola()')
)
)
)
}
ClusterOption = function(){
fluidRow(
style={'position:absolute;top:10px;right:40px;z-index:999;padding:1em;'},
actionButton(
inputId='cog_button',
label='Clustering Options',
onclick='$("#CLUST_OPTIONS,#hub_button,#swap_button").toggle("slow","swing")'),
div(
style='display:none;background:white;padding:1em;width:15em;',id = 'CLUST_OPTIONS',
selectInput(inputId='CLUSTER_METHOD',label='Distance type',choices = c("MM","pMM2",'Kappa'),selected = 'pMM2'),
numericInput(inputId='CLUSTER_MIN_SIZE',label='Minimum seed size',value=5,min=3,max=10,step=1),
numericInput(inputId='CLUSTER_MIN_DISTANCE',label='Maximum Distance',value=0.4,min=0,max=1,step=0.05),
actionButton(inputId='CLUSTER_CHANGE',label='APPLY'),
hr(),
p('Distance Converter', style={'font-weight:bold'}),
fluidRow(
column(selectInput(inputId='TEMP1',choices=c('MM','pMM','Kappa'),selected='MM',label='From'),width=6),
column(selectInput(inputId='TEMP2',choices=c('MM','pMM','Kappa'),selected='MM',label='To'),width=6)
),
fluidRow(
column(numericInput(inputId='TEMP3',value=NULL,label=NULL),width=6),
column(numericInput(inputId='TEMP4',value=NULL,label=NULL),width=6)
),
actionButton(inputId='TRANSFORM_ACTIVATE',label="Transform")
)
)
}
BuildGeneNetwork = function(){
fluidRow(
style={'position:absolute;top:50px;right:40px;z-index:999;padding:1em;'},
actionButton(
inputId='swap_button',
label='Gene Network',
onclick='$("#GENENETWORK_OPTIONS,#cog_button,#hub_button").toggle("slow","swing");'
),
div(
style='display:none;background:white;padding:1em;',id='GENENETWORK_OPTIONS',
verticalLayout(
selectizeInput(inputId='menuI',label='SELECT CLUST',choices='NOT BUILT YET',selected=NULL),
sliderInput(inputId='PPI_CUTOFF',label="PPI Cutoff: ",min=0,max=999,value=700,step=10),
checkboxInput(inputId='GRAY_EDGE',label='Combined Score',value=TRUE),
uiOutput(outputId="my_cbgi"),
actionButton(inputId = "DRAW_GENENETWORK", label = "Draw Gene Network"),
hr(),
div(
id='HUB_DIV',style='display:none',
numericInput(inputId = 'DEGREE_CUTOFF',label = "Find hubgene with DEGREE rank <= ",value = 3),
actionButton(inputId = "DEGREE",label = "Search"),
DT::dataTableOutput(outputId ='DEGREE_OUTPUT'),
hr()
),
actionButton(inputId = 'RESTORE_GENESET_NETWORK',label = 'Reset',icon = icon('undo'))
),
width = 12
)
)
}
HubBox = function(){
fluidRow(
style={'position:absolute;top:90px;right:40px;z-index:999;padding:1em;'},
actionButton(
inputId = 'hub_button',
label = 'Hub',
onclick='$("#HUB_OPTIONS,#swap_button, #cog_button").toggle("slow","swing")'
),
div(
style='display:none;background:white;padding:1em;',id='HUB_OPTIONS',
verticalLayout(
numericInput('RANK_CUTOFF',"Find Hubgenes around clusters with rank <=",value = 3),
actionButton('CHECK','around all clutser'),
tableOutput(outputId = "HUB_TABLE")
),
width = 12
)
)
}
Disease_Table = function(){
fluidRow(
style={'position:absolute;top:17em;left:2em;z-index:999;'},
actionButton(
inputId = 'Disease_button',
label = 'Disease',
onclick = '$("#Disease_Table").toggle("slow","swing")'
,style='display:none'
),
div(
style='background:white;padding:1em;',
id = 'Disease_Table',
DT::dataTableOutput(outputId ='dTable_OUTPUT')
,width = 12
)
)
}
UI_tabItems = function(){
tabItems(
tabItem(
tabName = "Genesets",
InputBox(),
hidden(
fluidRow(
id='main_panel',
box(
NodeSearch(),
NodeSearchSubmit(),
ClusterLegend(),
Download_SVG(),
Download_SUBPPI(),
LayoutButton(),
ClusterOption(),
BuildGeneNetwork(),
HubBox(),
Disease_Table(),
rcytoscapejs::rcytoscapejsOutput(outputId = 'plot1'),
width = 12
)
))
),
tabItem(
tabName = 'Clusters',
p(id = 'cluster_message','GSCluster not activated, information will show after RUN'),
hidden(
fluidRow(
id='cluster_row',
box(
DT::dataTableOutput(outputId = 'gsinfo'),
downloadButton(outputId = 'CLUST_RESULT',label= 'CLUSTERING_RESULT'),
width = 12
)
)
)
),
tabItem(
tabName = 'Downloads',
fluidRow(
box(
title = 'Human',
downloadButton('HGS', 'Example Geneset file'),
downloadButton('HGS2', 'Example Genescore file'),
width = 4
),
box(
title = 'Arabidopsis',
downloadButton('AGS', 'Example Geneset file'),
downloadButton('AGS2', 'Example Genescore file'),
width = 4
),
box(
title = 'Celegans',
downloadButton('CGS', 'Example Geneset file'),
downloadButton('CGS2', 'Example Genescore file'),
width = 4
)
),
fluidRow(
box(
title = 'Ecoli',
downloadButton('EGS', 'Example Geneset file'),
downloadButton('EGS2', 'Example Genescore file'),
width = 4
),
box(
title = 'Fly',
downloadButton('FGS', 'Example Geneset file'),
downloadButton('FGS2', 'Example Genescore file'),
width = 4
),
box(
title = 'Mouse',
downloadButton('MGS', 'Example Geneset file'),
downloadButton('MGS2', 'Example Genescore file'),
width = 4
)
),
fluidRow(
box(
title = 'Rat',
downloadButton('RGS', 'Example Geneset file'),
downloadButton('RGS2', 'Example Genescore file'),
width = 4
),
box(
title = 'Yeast',
downloadButton('YGS', 'Example Geneset file'),
downloadButton('YGS2', 'Example Genescore file'),
width = 4
),
box(
title = 'Zebrafish',
downloadButton('ZGS', 'Example Geneset file'),
downloadButton('ZGS2', 'Example Genescore file'),
width = 4
)
)
),
tabItem(
tabName='README',
uiOutput("pdfview")
)
)
}
ui = function(){
dashboardPage(
header = UI_header(),
sidebar = UI_sidebar(),
body = dashboardBody(
useShinyjs(), # useshinyjs in body
extendShinyjs(text = jsCode),
tags$head(tags$style(HTML('
.skin-blue .main-header .logo {
background-color: #3c8dbc;
}
.skin-blue .main-header .logo:hover {
background-color: #3c8dbc;
}
'))),
tags$style(type = "text/css", "#plot1 {height: calc(100vh - 125px) !important;}"),
tags$style(type = "text/css", "#pdfview {height: calc(100vh - 80px) !important;}"),
tags$head(tags$script(src="cytoscape-cy-svg-convertor.js")),
tags$head(tags$script(src="cytoscape-svg-convertor.js")),
tags$head(tags$script(src="svg.min.js")),
tags$head(tags$script(src="additional_script.js")),
tags$link(rel = "stylesheet", type = "text/css", href = "stylesheet.css"),
div(id='create', display='none'), # EMPTY DIV use to download SVG
UI_tabItems()
)
)}
function_buildlegends = function(colors){
res = c()
colors = setdiff(unique(colors), '#666666')
for(i in 1:length(colors)){
b = HTML(
paste0(
'<div style="background:',
colors[i],
';margin-bottom:0.3em;width:20px;height:20px;display:inline-block"></div>',
'<div style="float:right;text-align:center;height:20px;line-height:20px;width:70px;">Cluster ',
i,'</div><br>'
)
)
res = paste0(res,b)
}
return(HTML(res))
}
my_checkboxGroupInput = function(variable, label, choices, selected, colors){
choices_names <- choices
if(length(names(choices))>0) {choices_names = names(choices)}
my_colors = rep("black", length(choices))
is_selected = choices %in% selected
my_colors[is_selected] = colors[is_selected]
div(
id=variable,
class="form-group shiny-input-checkboxgroup shiny-input-container shiny-bound-input",
HTML(
paste0('<label class="control-label" for="',variable,'">',label,'</label>')
),
div(
class="shiny-options-group",
HTML(
paste0(
'<div class="checkbox" style="color:', my_colors, '">',
'<label>',
'<input type="checkbox" name="', variable,
'" value="', choices,
'"', ifelse(is_selected, 'checked="checked"', ''),
'/>',
'<span>', choices_names,'</span>',
'</label>',
'</div>', collapse = " "
)
)
)
)
}
my_names = c('Neighborhood','Gene Fusion',"Cooccurence",'Coexpression','Experiments','Databases','Textmining')
my_selected = my_names[1:5]
my_colors = c('red','orange','yellow', 'green', 'blue','navy','purple')
function_downloadHandler_Clust_info = function(gsinfo){
tmp = gsinfo
tmp[,1] = sapply(tmp[,1],FUN = function(i){gsub('\n','',i)})
colnames(tmp) = c('Name','Qvalue','Member', 'Cluster')
downloadHandler(
filename = 'Cluster_info.csv',
content = function(con){write.csv(tmp,con)}
)
}
get_matrix = function(genes, ppi_matrix){
rp = rownames(ppi_matrix)
genes_idx = unlist(sapply(genes, function(i){
a = which(rp==i)
if(length(a)>0){return(a)}
}))
return(ppi_matrix[genes_idx, genes_idx])
}
build_multiEdge = function(GENE_NETWORK_OBJ, MULTIEDGE){
genes = GENE_NETWORK_OBJ$nodeData$id
edges = GENE_NETWORK_OBJ$edgeData
myf = function(genes, li, col, edges){
source = c()
target = c()
color = c()
for(i in 1:length(genes)){
e1 = edges[which(edges$source == genes[i]),]
sel = intersect(genes, li[[genes[i]]])
sel = sel[which(sel < genes[i])] # to build one way edge
if(length(sel)>0){ # add edge
for(j in 1:length(sel)){
if(length(which(e1$target==sel[j]))>0){
source = c(source, genes[i])
target = c(target, sel[j])
color = c(color, col)
}
}
}
}
return(data.frame(cbind(source, target, color)))
}
edgeData = myf(genes,li1,col = 'red', edges)
if("Gene Fusion"%in%MULTIEDGE){
edgeData = rbind(edgeData, myf(genes,li2,col = 'orange', edges))}
if("Cooccurence"%in%MULTIEDGE){
edgeData = rbind(edgeData, myf(genes,li3,col = 'yellow', edges))}
if("Coexpression"%in%MULTIEDGE){
edgeData = rbind(edgeData, myf(genes,li4,col = 'green', edges))}
if("Experiments"%in%MULTIEDGE){
edgeData = rbind(edgeData, myf(genes,li5,col = 'blue', edges))}
if("Databases"%in%MULTIEDGE){
edgeData = rbind(edgeData, myf(genes,li6,col = 'navy', edges))}
if("Textmining"%in%MULTIEDGE){
edgeData = rbind(edgeData, myf(genes,li7,col = 'purple', edges))}
if(!"Neighborhood"%in%MULTIEDGE){edgeData = edgeData[-which(edgeData[,'color']=='red'),]}
if(length(edgeData)==0){return(NULL)}
return(edgeData)
}
build_GSINFO = function(DATA, QV_CUTOFF){
for(i in 1:length(DATA)){
temp = strsplit(DATA[i],'\t')[[1]]
GS_NAME = temp[1]
GS_MEMBER = strsplit(temp[2],' ')[[1]]
GS_QVALUE = as.numeric(temp[3])
if(GS_QVALUE > QV_CUTOFF){next}
GS[i] = GS_NAME
GM[[i]] = GS_MEMBER
GQ[i] = GS_QVALUE
}
return(list(GS=GS, GM=GM, GQ=GQ))
}
get_nodeColor = function(id){
if(length(id)==0){return(0)}
sapply(1:length(id), FUN = function(i){a = gene_colors[id[i]]; if(is.na(a)){return('#FFFFFF')};return(a)})
}
clique60 = function(g){
res = list()
nv = function(g,lc){
gs = neighbors(g,lc)
for(i in 2:length(lc)){ gs = igraph::union(gs,neighbors(g,lc[i])) } # get all nodes linked with cliques;
gs = difference(gs,lc) # remove clique itself;
return(gs)
}
while(TRUE){
lc = largest.cliques(g)[[1]] # get largest clique
if(length(lc)<4){return(res)} # if largest size < 4 , return;
res[[length(res)+1]] = attributes(lc)$names
gs = nv(g,lc)
if(length(gs)!=0){
sel = which(sapply(gs, function(i){ ( sum(sapply(lc, function(j){ are_adjacent(g,j,i)}))/length(lc) ) > 0.6 })) # select nodes with linked with clique > 60%
if(length(sel)>0){
lc = igraph::union(lc,gs[sel])
res[[length(res)]] = attributes(lc)$names
} # add them to clique then, remove them
}
g = g-lc
}
return(res)
}
apply_cliq60 = function(network){
nodeData = network$nodeData[,1:2]
edgeData = network$edgeData
color = network$color
if(is.null(color)){color = as.character(network$nodeData[,'color'])} # GENE NETWORK
width = network$width
shape = rep('ellipse',nrow(nodeData))
height = rep('50px',nrow(nodeData))
width = rep('50px',nrow(nodeData))
cliqlist = clique60(graph.data.frame(edgeData, directed = F))
for(i in 1:length(cliqlist)){ # for test result
this_cliq = cliqlist[[i]]
# add "Super node" , and it's color
id = paste0('Module',i)
supernode = c(id,id) # supernode = white;
nodeData = rbind(nodeData, supernode)
#e17055 : BROWN
#32ff7e : flour green
#fced20 : YELLOW
color = c(color,'#fced20')
shape = c(shape,'ellipse')
height = c(height,'100px')
width = c(width,'100px')
# remove edge between this cliq
v = intersect(which(sapply(1:nrow(edgeData), function(i){edgeData[i,1] %in% this_cliq})),
which(sapply(1:nrow(edgeData), function(i){edgeData[i,2] %in% this_cliq})))
if(length(v)!=0){edgeData = edgeData[-v,]}
# add edge Supernode and them.
if(ncol(edgeData) ==3){
for(j in 1:length(this_cliq)){
superEdge = c(id,this_cliq[j], '#666666')
edgeData = rbind(edgeData,superEdge)
# width = c(width,5.495) # 0.5
}
}
else{
for(j in 1:length(this_cliq)){
superEdge = c(id,this_cliq[j])
edgeData = rbind(edgeData,superEdge)
# width = c(width,5.495) # 0.5
}
}
}
nodeData = cbind(nodeData, color, shape, height, width)
return(list (nodeData = nodeData, edgeData = edgeData, color = nodeData$color))
}
get_dist_OP = function(gsl, ppi_matrix = string, clust_method){
d = length(gsl)
gsl_dist = matrix(0,d,d)
pre_OP = function(gsl, rp){
res = list()
for(i in 1:length(gsl)){
a = unlist(sapply(gsl[[i]], function(i){a=which(rp==i); if(length(a)){return(a)}}))
names(a) = NULL
res[[i]] = a
}
return(res)
}
Distance_OP = function(gs1, gs2, gsi1, gsi2){
interact = function(idx1,idx2, tab){
if(length(idx1)==0 | length(idx2)==0){return(0)}
return(sum(tab[idx1,idx2]) )
} # / 1000?
interact2 = function(idx1,idx2, tab,k){
if(length(idx1)==0 | length(idx2)==0){return(0)}
return(sum(tab[idx1,idx2]^(1/k)) )
} # / 1000?
get_score = function(main, sub, lc, lm, ls){
common = intersect(main,sub)
uniq = setdiff(sub, common);
uniq2 = setdiff(main,sub);
w = ls/(lm+ls)
nom = interact(common,uniq, ppi_matrix)*w+interact(uniq2,uniq, ppi_matrix);
denom = w*lc+lm-lc
score = 1-((lc+nom/denom)/ls)
return(score)
}
score1 = function(A,B,idx_A,idx_B){
w = min(length(A), length(B))/ (length(A)+length(B)) # 0.5633803
m = min(length(A),length(B)) # 93
i = length(intersect(A,B)) # 93
uniqA = setdiff(idx_A,idx_B)
uniqB = setdiff(idx_B,idx_A)
common = intersect(idx_A,idx_B)
nom = w*interact(uniqA,common,ppi_matrix)+interact(uniqA,uniqB,ppi_matrix)
denom = w*i+length(setdiff(B,A))
1- (i+nom/denom)/m
}
score2 = function(A,B,idx_A,idx_B,k=5){
w = min(length(A), length(B))/ (length(A)+length(B)) # 0.5633803
a = length(A)
i = length(intersect(A,B))
uniqA = setdiff(idx_A,idx_B)
uniqB = setdiff(idx_B,idx_A)
common = intersect(idx_A,idx_B)
nom = w*interact2(uniqA,common,ppi_matrix,k) + interact2(uniqA,uniqB,ppi_matrix,k)
#nom = w*interact(uniqA,common,ppi_matrix) + interact(uniqA,uniqB,ppi_matrix)
denom = w*i+length(setdiff(B,A))
#1-(i*k+nom/denom*(1-k))/a
1-(i+nom/denom)/a
}
score3 = function(A,B,idx_A,idx_B,k=.8){
w = min(length(A), length(B))/ (length(A)+length(B)) # 0.5633803
a = length(A)
i = length(intersect(A,B))
uniqA = setdiff(idx_A,idx_B)
uniqB = setdiff(idx_B,idx_A)
common = intersect(idx_A,idx_B)
nom = w*interact(uniqA,common, ppi_matrix)+interact(uniqA,uniqB, ppi_matrix)
denom = w*i+length(setdiff(B,A))
1-(i+(nom/denom)^(1/k))/a
}
if(clust_method =='pMM1'){
score = min(score1(gs1,gs2,gsi1,gsi2), score1(gs2,gs1,gsi2,gsi1))
}
else if(clust_method=='pMM2'){
score = min(score2(gs1,gs2,gsi1,gsi2), score2(gs2,gs1,gsi2,gsi1))
}
else if(clust_method=='pMM3'){
score = min(score3(gs1,gs2,gsi1,gsi2), score3(gs2,gs1,gsi2,gsi1))
}
else{
gsl1 = length(gs1)
gsl2 = length(gs2)
lc = length(intersect(gs1, gs2))
lm = max(gsl1,gsl2)
ls = min(gsl1,gsl2)
if(gsl1>gsl2){score = get_score(gsi1,gsi2, lc, lm, ls)}
else if(gsl2>gsl1){score = get_score(gsi2,gsi1, lc, lm, ls)}
else{ score = min(get_score(gsi1,gsi2, lc, lm, ls), get_score(gsi2,gsi1, lc, lm, ls)) }
}
if(score == 0){score = 0.001}
return(score)
}
gslp = pre_OP(gsl, rownames(string))
for(i in 1:d){
if(i%%10==0){print(i)}
for(j in 1:d){
if(i>j){ gsl_dist[i,j] = gsl_dist[j,i]; next}
if(i==j){ gsl_dist[i,j] = 0.001; next}
gsl_dist[i,j] = Distance_OP(gsl[[i]],gsl[[j]], gslp[[i]], gslp[[j]])
}
}
return(gsl_dist);
}
get_dist_K = function(gsl){
ALLGENE = length(unique(unlist(gsl)))
d = length(gsl)
gsl_dist = matrix(0,d,d)
Distance_K = function(gs1,gs2){
l = ALLGENE
A = length(intersect(gs1, gs2))
B = length(setdiff(gs1,gs2))
C = length(setdiff(gs2,gs1))
D = ALLGENE - (A+B+C)
O = (A+D)/l;
E = ((A+C)*(A+B)+(B+D)*(C+D))/(l*l);
kappa = (O-E)/(1-E);
return(1-kappa)
}
for(i in 1:d){
for(j in 1:d){
if(i>j){ gsl_dist[i,j] = gsl_dist[j,i] }
else if(i==j){ gsl_dist[i,j] = 0 }
else { gsl_dist[i,j] = Distance_K(gsl[[i]], gsl[[j]]) }
}
}
return(gsl_dist)
}
build_datatable = function(gsinfo){
dtres = datatable(
gsinfo,
filter = 'top',
options = list(
lengthChange = TRUE,
pageLength = 10,
columnDefs = list(list(targets = c(3), searchable = FALSE)),
autoWidth = TRUE,
scrollX = TRUE,
scrollY = TRUE
),
colnames = c("Name", 'Qvalue', 'Member', 'Cluster'),
selection = 'none'
)
}
update_input = function(session,lugi4){ # length(unique(gsinfo[,4]))
updateSelectizeInput(
session,
inputId = 'menuI',
label = 'Gene Network in Cluster',
choices = 1:lugi4
)
}
update_input2 = function(session,lugi4){ # length(unique(gsinfo[,4]))
updateSelectizeInput(
session,
inputId = 'menuI_INCOLOR',
label = 'select Cluster',
choices = 1:lugi4
)
}
find_degree = function(network_obj){
# for gene network
edgeData = network_obj$edgeData
nodeData = network_obj$nodeData$id
nodes = unique(nodeData)
res = sapply(1:length(nodes), FUN = function(i){
this_node = nodes[i]
connected = length(intersect(
union(
which(edgeData['source'] == this_node),
which(edgeData['target'] == this_node)),
which(edgeData['color']== '#666666')
))
return(connected)
})
names(res) = nodes
return(res)
}
summary_dist = function(m){
v = as.numeric(m)
v = v[which(v<max(v) & v>min(v))]
quantile(v,seq(0,1,0.01))
}
server <- function(input, output, session) {
GM = 'NULL'
GS = 'NULL'
GQ = 'NULL'
GENE_NETWORK_OBJ = 'NULL'
clusts = 'NULL'
output$AGS = downloadHandler(
filename = 'ara_sample_geneset.txt',
content <- function(file) { file.copy("samples/arabidopsis/sample_geneset.txt", file)}
)
output$AGS2 = downloadHandler(
filename = 'ara_sample_genescore.txt',
content <- function(file) { file.copy("samples/arabidopsis/sample_genescore.txt", file)}
)
output$CGS = downloadHandler(
filename = 'cel_sample_geneset.txt',
content <- function(file) { file.copy("samples/celegans/sample_geneset.txt", file)}
)
output$CGS2 = downloadHandler(
filename = 'cel_sample_genescore.txt',
content <- function(file) { file.copy("samples/celegans/sample_genescore.txt", file)}
)
output$EGS = downloadHandler(
filename = 'eco_sample_geneset.txt',
content <- function(file) { file.copy("samples/ecoli/sample_geneset.txt", file)}
)
output$EGS2 = downloadHandler(
filename = 'eco_sample_genescore.txt',
content <- function(file) { file.copy("samples/ecoli/sample_genescore.txt", file)}
)
output$FGS = downloadHandler(
filename = 'fly_sample_geneset.txt',
content <- function(file) { file.copy("samples/fly/sample_geneset.txt", file)}
)
output$FGS2 = downloadHandler(
filename = 'fly_sample_genescore.txt',
content <- function(file) { file.copy("samples/fly/sample_genescore.txt", file)}
)
output$HGS = downloadHandler(
filename = 'hum_sample_geneset.txt',
content <- function(file) { file.copy("samples/human/sample_geneset.txt", file)}
)
output$HGS2 = downloadHandler(
filename = 'hum_sample_genescore.txt',
content <- function(file) { file.copy("samples/human/sample_genescore.txt", file)}
)
output$MGS = downloadHandler(
filename = 'mou_sample_geneset.txt',
content <- function(file) { file.copy("samples/mouse/sample_geneset.txt", file)}
)
output$MGS2 = downloadHandler(
filename = 'mou_sample_genescore.txt',
content <- function(file) { file.copy("samples/mouse/sample_genescore.txt", file)}
)
output$RGS = downloadHandler(
filename = 'rat_sample_geneset.txt',
content <- function(file) { file.copy("samples/rat/sample_geneset.txt", file)}
)
output$RGS2 = downloadHandler(
filename = 'rat_sample_genescore.txt',
content <- function(file) { file.copy("samples/rat/sample_genescore.txt", file)}
)
output$YGS = downloadHandler(
filename = 'yea_sample_geneset.txt',
content <- function(file) { file.copy("samples/yeast/sample_geneset.txt", file)}
)
output$YGS2 = downloadHandler(
filename = 'yea_sample_genescore.txt',
content <- function(file) { file.copy("samples/yeast/sample_genescore.txt", file)}
)
output$ZGS = downloadHandler(
filename = 'zeb_sample_geneset.txt',
content <- function(file) { file.copy("samples/zebrafish/sample_geneset.txt", file)}
)
output$ZGS2 = downloadHandler(
filename = 'zeb_sample_genescore.txt',
content <- function(file) { file.copy("samples/zebrafish/sample_genescore.txt", file)}
)
output$my_cbgi = renderUI({})
outputOptions(output, "my_cbgi", suspendWhenHidden = FALSE)
output$HUB_TABLE = renderUI({})
outputOptions(output, "HUB_TABLE", suspendWhenHidden = FALSE)
output$pdfview <- renderUI({
tags$iframe(style="height:100%; width:100%", src="GScluster User Manual.pdf")
})
observeEvent(input$TRANSFORM_ACTIVATE,{
T1 = input$TEMP1
T2 = input$TEMP2
V1 = input$TEMP3
tpm = function(T1, T2, V1){
if(T1=='MM'){v = as.numeric(distO)}
if(T1=='pMM'){v = as.numeric(distOP)}
if(T1=='Kappa'){v = as.numeric(distK)}
if(T2=='MM'){v2 = as.numeric(distO)}
if(T2=='pMM'){v2 = as.numeric(distOP)}
if(T2=='Kappa'){v2 = as.numeric(distK)}
as.numeric(quantile(v2, ecdf(v)(V1)))
}
updateNumericInput(session, inputId = 'TEMP4',value = tpm(T1,T2,V1))
})
build_genescore_filter = function(Data){
res = c()
for(i in 1:length(Data)){
temp = strsplit(Data[i],'\t')[[1]]
if(as.numeric(temp[2])>input$GENESCORE_CUTOFF){next}
res= c(res,temp[1])
}
return(res)
}
build_gene_colorlist = function(Data){
res = sapply(1:length(Data), FUN = function(i){
temp = strsplit(Data[i],'\t')[[1]]
GENE = temp[1]
GENESCORE = as.numeric(temp[2])
ret = GENESCORE
names(ret) = GENE
return(ret)
})
res = res[which(res<input$GENESCORE_CUTOFF)]
stats = summary(res)
Q1 = stats[2]
Q2 = stats[3]
Q3 = stats[5]
res2 = res
res2[which(res<=Q1)] = '#FBCDCD'
res2[which(res>Q1 & res<=Q2)] = '#F89A9A'
res2[which(res>Q2 & res<=Q3)] = '#F46767'
res2[which(res>Q3) ] = '#F03434'
res = res2
### COLOR LIST
# 255,255,255 # NONE, FFFFFF
# 251,205,205 # ~ Q1 FBCDCD
# 248,154,154 # Q1 ~ Q2 F89A9A
# 244,103,103 # Q2 ~ Q3 F46767
# 240,52,52 # Q3 ~ F03434
return(res)
}
build_genenetwork = function(genes, ppi_cutoff = 0.7, ppi_matrix, multiEdge = TRUE, showError = TRUE){
if(input$PPI_CUTOFF!=700){ppi_cutoff = input$PPI_CUTOFF/1000}
# build edges
tab = get_matrix(genes, ppi_matrix)
source = c()
target = c()
w = c()
calculate_edgeW = function(i){ return(round(i/0.111+(10-1/0.111),3)) }
rd = rownames(tab)
for(i in 1:nrow(tab)){
v = setdiff(which(tab[i,] >= ppi_cutoff),i)
if(is.null(names(v))){names(v) = rd[v]}
if(length(v) > 0){v = v[which( names(v) < rd[i] )]}
if(length(v) > 0){
sel = names(v)
source = c(source, rep(rd[i], length(sel)))
target = c(target, sel)
w = c(w,sapply(tab[i,names(v)], calculate_edgeW))
}
}
color = rep('#666666', length(source))
edgeData <- data.frame(source, target, color, stringsAsFactors=FALSE)
# build nodes
id = unique(union(source, target))
name = id
nodeData = data.frame(id, name, stringsAsFactors=FALSE)
if(exists('gene_colors')){
color = get_nodeColor(id)
if(length(color) == 1){
if(color==0){
if(showError){ showNotification("NO GENES WITH CUTOFF", type = 'error') }
return()
}
}
nodeData = cbind(nodeData, color)
}
else{ showNotification("GENESCORE FILE NOT GIVEN", type = 'error') }
# remove edge between white nodes
whiteNodes = nodeData[which(nodeData['color']=='#FFFFFF'),'id']
v = intersect(which(sapply(1:nrow(edgeData), function(i){edgeData[i,1] %in% whiteNodes})),
which(sapply(1:nrow(edgeData), function(i){edgeData[i,2] %in% whiteNodes})))
if(length(v)!=0){edgeData = edgeData[-v,]}
# remove whitenode with enoughrednode
redNodes = nodeData[which(nodeData['color']!='#FFFFFF'),'id']
edgesBetweenredNodes = intersect(which(sapply(1:nrow(edgeData), function(i){edgeData[i,1] %in% redNodes})),
which(sapply(1:nrow(edgeData), function(i){edgeData[i,2] %in% redNodes})))
edgesBetweenredNodes = edgeData[edgesBetweenredNodes,]
enoughredNodes = union(edgesBetweenredNodes[,1],edgesBetweenredNodes[,2])
notenoughredNodes = setdiff(redNodes, enoughredNodes)
for(i in 1:length(whiteNodes)){
this_node = whiteNodes[i]
v = union(which(edgeData[,1] == this_node),which(edgeData[,2] == this_node))
if(length(v)==1){
if(edgeData[v,1] %in% enoughredNodes | edgeData[v,2] %in% enoughredNodes){
edgeData = edgeData[-v,]
}
}
}
# remove nodes without edges
edgeNodes = union(edgeData[,"source"], edgeData[,"target"])
v = which(sapply(1:nrow(nodeData), function(i){nodeData[i,1] %in% edgeNodes}))
if(length(v)!=0){nodeData = nodeData[v,]}
GENE_NETWORK_OBJ = list(nodeData = nodeData, edgeData = edgeData, width = w)
if(length(input$MULTIEDGE)>0){
multi_edge = build_multiEdge(GENE_NETWORK_OBJ, input$MULTIEDGE)
GENE_NETWORK_OBJ$edgeData = rbind(GENE_NETWORK_OBJ$edgeData, multi_edge)
}
return(GENE_NETWORK_OBJ)
}
build_cytoscape_network = function(clusts_table, Dist){
build_col = function(i){
sapply(1:i, FUN = function(i){
k = round(runif(3,min = 0,max = 255))
return(rgb(k[1],k[2],k[3],max=255))
})
}
cl1 = sapply(clusts_table[,1], function(i){gsub('\n','',i)}, USE.NAMES = FALSE) # remove \n
name = id = unique(cl1)
nodeData = data.frame(id, name, stringsAsFactors=FALSE)
col = build_col(length(unique(clusts_table[,4])))
color = sapply(1:length(id), FUN = function(i){
a = which(id[i]==cl1)
if(length(a)>1){return('#666666')}
else{return(col[clusts_table[a,4]])}
})
nodeData = cbind(nodeData, color)
rd = rownames(Dist) # replace GS??
EDGED = input$CLUSTER_MIN_DISTANCE
source = c()
target = c()
w = c()
rd_idx = sapply(id, function(i){a = which(i==rd); if(length(a)>1){a[1]} else{a}}, USE.NAMES = FALSE)
Dist = Dist[rd_idx,rd_idx]
rd = rownames(Dist)
calculate_edgeW = function(i){ return(round(i/0.111+(10-1/0.111),3)) }
for(i in 1:length(rd_idx)){
v = which(Dist[i,-i]<=EDGED)
if(length(v)>0){v = v[which(names(v)<rd[i])]}
if(length(v)>0){
sel = names(v)
source = c(source, rep(rd[i], length(sel)))
target = c(target, sel)
w = c(w,sapply(Dist[i,names(v)], calculate_edgeW))
}
}
edgeData <- data.frame(source, target, stringsAsFactors=FALSE)
return(list (nodeData = nodeData, edgeData = edgeData, color = color, width = w))
}
fuzzy_clust = function(var_D = 0.5, Dist, dist_type, GS, GM, GQ){
neighbor = function(vector, var_D){ return(which(vector<=var_D)) }
find_ratio = function(v){
l = length(v)
if(l==1){return(0)}
count = ( length(which(Dist[v, v]<var_D)) - l )
return( count/(l^2-l) )
}
remove_duplicated = function(track){ return(track[which(!duplicated(track))]) }
remove_included = function(track){
remove = c()
for(i in 1:(length(track)-1)){
for(j in (i+1):length(track)){
if(ovl(track[[i]],track[[j]])==1){
if(length(track[[i]])>length(track[[j]])){ remove = c(remove,j) }
else{ remove = c(remove,i) }
}
}
}
if(length(remove)>0){track = track[-remove]}
return(track)
}
track_gene = function(idx){
res = c();
for(i in 1:length(idx)){ res = c(res, geneset_member[idx[i]]) }
return(sort(unique(res)))
}
track2genelist = function(track){ lapply(1:length(track), FUN = function(i){ unique(unlist(GM[track[[i]]], use.names = FALSE)) })}
var_M = var_D
var_X = input$CLUSTER_MIN_SIZE
var_w = 0.5
track = list()
for(i in 1:nrow(Dist)){
v = neighbor(Dist[i,], var_D)
track[[i]] = sort(v)
}
track = track[which(unlist(lapply(track, length))>=var_X)]
track = track[which(unlist(lapply(track, find_ratio))>=var_w)] # ratio cutoff
names(track) = NULL
min_dis = -9999;
while(min_dis <= var_M){
track = remove_duplicated(track)
track = remove_included(track)
track_genelist = track2genelist(track)
if(dist_type==1){ Dist = get_dist_O(track_genelist) }
if(dist_type==2){ Dist = get_dist_OP(track_genelist, ppi_matrix = string, input$CLUSTER_METHOD)}
if(dist_type==3){ Dist = get_dist_K(track_genelist) }
# merge and move
track2 = lapply(1:length(track), FUN = function(i){sort(unique(unlist(track[which(Dist[i,]<var_M)]))) })
track = remove_included(track2)
track = remove_duplicated(track)
track_genelist = track2genelist(track)
min_dis = 9999;
if(length(track)==1){break}
if(dist_type==1){Dist = get_dist_O(track_genelist)}
if(dist_type==2){Dist = get_dist_OP(track_genelist, ppi_matrix = string, input$CLUSTER_METHOD)}
if(dist_type==3){Dist = get_dist_K(track_genelist)}
min_dis = min(sapply(1:nrow(Dist), FUN = function(i){min(Dist[i, -i])}))
}
return(track) # return index form
}
get_clust_gs = function(i, query = FALSE){
GS = gsinfo[which(gsinfo[,4] == i),1]
GS = sapply(GS, function(i){gsub('\n','',i)}, USE.NAMES=FALSE)
if(query){ GS = paste(GS, collapse=',#') }
return(GS)
}
get_clust_gm = function(clust_no){#, selected_idx){
genemember = unlist(global_gsm[which(gsinfo[,4] == clust_no)])#[selected_idx]])
res = c()
genemember = sapply(genemember, function(i){gsub('\n',',',i)}) # remove \n
for(i in 1:length(genemember)){ res = c(res,strsplit(genemember[i],',')[[1]]) }
res = unique(res)
return(res)
}
my = reactiveValues(selected=my_selected, firt_call_ignore=TRUE)
output$my_cbgi = renderUI( my_checkboxGroupInput( "MULTIEDGE", "Evidence :", choices = my_names, selected = my$selected, colors = my_colors ) )
observeEvent(input$MULTIEDGE,{
if(my$firt_call_ignore){my$firt_call_ignore=FALSE}
else{my$selected <- input$MULTIEDGE}},
ignoreNULL = FALSE
)
observeEvent(input$AB1, {
print('go to sleep')
Sys.sleep(2)
myf = function(edgeData, w){ for(i in 1:nrow(edgeData)){ js$draw_edge( c(edgeData[i,1],edgeData[i,2], w[i]))}}
edgeData= GENESET_NETWORK_OBJ$edgeData
w = GENESET_NETWORK_OBJ$width
names(edgeData[,1]) = NULL
names(edgeData[,2]) = NULL
names(w) = NULL
myf(edgeData, w)
js$layout_as_cola()
})
observeEvent(input$Disease_button,{
clust_idx = input$menuI
genes = get_clust_gm(clust_idx)
working_gene = TRUE
if(working_gene){
genes = intersect(get_clust_gm(clust_idx), gene_score_filter)
}
if(length(genes)<=1){
showNotification("NO GENES SATISFIED THE GENE SCORE CUTOFF", type = 'error')
shinyjs::hide(id='Disease_button')
return()
}
dTable = build_Disease_Table(genes)
output$dTable_OUTPUT = renderDataTable(dTable)
})
observeEvent(input$AB2, {
print('go to sleep2')
Sys.sleep(2)
myf = function(edgeData, w){for(i in 1:nrow(edgeData)){ js$draw_edge( c(edgeData[i,1],edgeData[i,2], w[i])) }}
edgeData= GENE_NETWORK_OBJ$edgeData[,1:2]
w = GENE_NETWORK_OBJ$width
names(edgeData[,1]) = NULL
names(edgeData[,2]) = NULL
names(w) = NULL
myf(edgeData, w )
js$layout_as_cola()
})
observeEvent(input$ACTIVATEFIT,{
txt = gsub('\n','',input$FIT)
js$fit_node(txt)
})
observeEvent(input$RESTORE_GENESET_NETWORK, {
js$remove_cy()
shinyjs::hide(id='HUB_DIV')
shinyjs::hide(id='Disease_button')
shinyjs::hide(id='subPPI')
nodeData = GENESET_NETWORK_OBJ$nodeData
edgeData = GENESET_NETWORK_OBJ$edgeData
color = GENESET_NETWORK_OBJ$color
output$legend <- renderUI( function_buildlegends(color) )
GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
#GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData, edgeTargetShape = 'none',nodeLabelColor = 'black')
GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
updateSelectizeInput(session, "FIT", choices = unique(gsinfo[,1]), server = TRUE)
#GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
output$plot1 = rcytoscapejs::renderRcytoscapejs({
res = rcytoscapejs(
layout='cose',
nodeEntries = GENESET_NETWORK_OBJ$nodes,
edgeEntries = GENESET_NETWORK_OBJ$edges,
boxSelectionEnabled = FALSE)
return(res)
})
shinyjs::click('AB1')
})
bridge = function(network_obj){
# assume gene_network_obj
clust_idx = input$menuI
genes = get_clust_gm(clust_idx)
genes = intersect(rownames(string), genes)
exp = network_obj$nodeData$id
exp = intersect(rownames(string),exp)
#non_exp = setdiff(unique(unlist(GM)), exp)
non_exp = setdiff(genes, exp)
if(length(exp)==0){return(network_obj)}
matrix = string[exp,non_exp] # among non_expressed genes.
node_added = c()
# id , name, color
for(i in 1:length(exp)){
linked_genes = names(which(matrix[i,]>0))
node_added = c(node_added, linked_genes)
}
if(length(node_added)>0){
tn = table(node_added)
# node
# #7efff5 SKYBLUE
# #fbc531 YELLOW
# #e67e22 ORANGE
node_added = names(which(tn > (length(exp)*2/(3+1)) ))
i = 2
while(length(node_added)>20){
i = i+1
node_added = names(which(tn > (length(exp)*i/(i+1)) ))
}
v = data.frame(id=node_added, name = node_added, color = '#e67e22', shape='rectangle', height='30px',width = '30px')
network_obj$nodeData = rbind(network_obj$nodeData, v)
# bridge - intersect
targets = list()
for(i in 1:length(node_added)){
this_source = node_added[i]
this_target = names(which(matrix[exp,this_source]>0))
targets[[i]] = this_target
names(targets)[i] = this_source
}
target_D = matrix(0,length(targets), length(targets))
for(i in 1:length(targets)){
for(j in 1:length(targets)){
if(i==j){target_D[i,j] = 1; next}
if(i>j){target_D[i,j] = target_D[j,i]; next}
target_D[i,j] = length(intersect(targets[[i]], targets[[j]])) / min(length(targets[[i]]), length(targets[[j]]))
}
}
# SELECTION P = 2/3
chunk = list()
remain = 1:length(targets)
while(length(remain)>0){
a = intersect(remain, which(target_D[remain[1],] > 2/3))
chunk[[length(chunk)+1]] = a
remain = setdiff(remain, a)
}
# chunk node
v = data.frame(
id = paste0('Bridge' ,1:length(chunk)),
name = paste0('Bridge' ,1:length(chunk)),
color = '#7efff5', shape='ellipse', height='20px',width = '20px')
network_obj$nodeData = rbind(network_obj$nodeData, v)
# chunk edge
# bridge -> exp
# light gray #aaa69d
for(i in 1:length(chunk)){
this_source = paste0('Bridge',i)
this_target = names(targets)[chunk[[i]]]
v = data.frame(source = this_source, target = this_target, color = '#aaa69d')
network_obj$edgeData = rbind(network_obj$edgeData, v)
}
# bridge -> exp
for(i in 1:length(chunk)){
this_nodes = unique(unlist(targets[chunk[[i]]]))
v = data.frame(source = paste0('Bridge',i), target = this_nodes, color = '#aaa69d')
network_obj$edgeData = rbind(network_obj$edgeData, v)
}
}
else{
print('no bridge')
}
return(network_obj)
}
observeEvent(input$DRAW_GENENETWORK,{
shinyjs::show(id = 'HUB_DIV')
shinyjs::show(id = 'subPPI')
shinyjs::show(id = 'Disease_button')
clust_idx = input$menuI
if(length(clust_idx)==0){showNotification("NONE CLUSTER SELECTED", type = 'error');return(NULL)}
genes = get_clust_gm(clust_idx)
working_gene = TRUE
if(working_gene){
genes = intersect(get_clust_gm(clust_idx), gene_score_filter)
}
if(length(genes)<=1){
showNotification("NO GENES SATISFIED THE GENE SCORE CUTOFF", type = 'error')
shinyjs::hide(id='HUB_DIV')
shinyjs::hide(id='subPPI')
shinyjs::hide(id='Disease_button')
return()
}
res = build_genenetwork(genes = genes, ppi_matrix = string)
if(is.null(res)){return()}
GENE_NETWORK_OBJ = res
assign('GENE_NETWORK_OBJ', GENE_NETWORK_OBJ, envir = .GlobalEnv)
GENE_NETWORK_OBJ <<- GENE_NETWORK_OBJ
function_downloadHandler_subPPI = function(i){
val = paste('Gene1','Gene2','PPI Score','Common Gene-set','Gene1 only','Gene2 only', sep='\t')
e = GENE_NETWORK_OBJ$edgeData
e = e[which(e[,'color']=='#666666'), ]
width = GENE_NETWORK_OBJ$width
genesets = gsinfo[which(gsinfo[,4] == i),]
genesets[,1] = sapply(genesets[,1],FUN = function(i){gsub('\n','',i)})
for(i in 1: nrow(e)){
ss = e$source[i]
tt = e$target[i]
ww = round((width[i]-(10-1/0.111))*0.111,3)
res = c()
ret = c()
for(j in 1:nrow(genesets)){
k = strsplit(as.character(genesets[j,3]),',')[[1]]
if(ss %in% k) res = c(res,genesets[j,1])
if(tt %in% k) ret = c(ret,genesets[j,1])
}
# gene1, gene2, ppi score, common geneset, gene1 only, gene2 only
within = intersect(res,ret)
res = setdiff(res,within)
ret = setdiff(ret,within)
temp = paste(ss,tt,ww, sep='\t') # gene1, gene2, score
if(length(within)>0) {
temp = paste(temp,paste(within,collapse=','), sep='\t' ) # common geneset
}
else{
temp = paste(temp, '...', sep='\t')
}
if(length(res)>0) {
temp = paste(temp,paste(res,collapse=','), sep='\t' ) # gene1 only
}
else{
temp = paste(temp, '...', sep='\t')
}
if(length(ret)>0) {
temp = paste(temp,paste(ret,collapse=','), sep='\t' ) # gene2 only
}
else{
temp = paste(temp, '...', sep='\t')
}
val = c(val,temp)
}
downloadHandler(filename='subppi.txt',content = function(con){writeLines(val,con)})
}
output$subPPI = function_downloadHandler_subPPI(input$menuI)
if(!input$GRAY_EDGE){
res$edgeData = res$edgeData[which(res$edgeData[,'color']!='#666666'),]
#genenetwork = createCytoscapeJsNetwork(res$nodeData, res$edgeData[which(res$edgeData[,'color']!='#666666'),], edgeTargetShape = 'none', nodeLabelColor = 'black')
}
# else{
#genenetwork = createCytoscapeJsNetwork(res$nodeData, res$edgeData, edgeTargetShape = 'none', nodeLabelColor = 'black')
#}
GNO2 = apply_cliq60(GENE_NETWORK_OBJ)
#genenetwork = createCytoscapeJsNetwork(res$nodeData, res$edgeData, edgeTargetShape = 'none', nodeLabelColor = 'black')
GNO2 = bridge(GNO2)
genenetwork = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData, edgeTargetShape = 'none', nodeLabelColor = 'black')
#res = createCytoscapeJsNetwork(res$nodeData, res$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
js$remove_cy()
output$plot1 = rcytoscapejs::renderRcytoscapejs({
rcytoscapejs(
nodeEntries = genenetwork$nodes,
edgeEntries = genenetwork$edges,
boxSelectionEnabled = FALSE,
layout='cola'
)
})
build_color_labels = function(){
res = c()
colors = c('#F03434','#F46767',"#F89A9A",'#FBCDCD')#,'#FFFFFF')
texts = c("Very Strong (0~25%)","Strong (25~50%)","Moderate (50~75%)","Weak (75~100%)")#,"NO SCORE")
for(i in 1:length(colors)){
b = HTML(
paste0(
'<div style="background:',
colors[i],
';margin-bottom:1em;width:20px;height:20px;display:inline-block; border :black solid 1px;"></div>',
'<div style="float:right;text-align:center;height:20px;line-height:20px;width:70px;"> ',
texts[i],'</div><br>'
)
)
res = paste0(res,b)
}
return(HTML(res))
}
dTable = build_Disease_Table(genes)
output$dTable_OUTPUT = renderDataTable(dTable)
output$legend <- renderUI( build_color_labels() )
updateSelectizeInput(session, "FIT", choices = unique(GNO2$nodeData$name), server = TRUE)
shinyjs::click('AB2')
})
observeEvent(input$CLUSTER_CHANGE, {
progress <- shiny::Progress$new()
on.exit(progress$close())
progress$set(message = "Building", value = 0)
var_D = input$CLUSTER_MIN_DISTANCE
v = 101
#distOP_calc = FALSE
progress$inc(1/2, detail = "Clustering")
while(v>100){
cluster_method = input$CLUSTER_METHOD
if(cluster_method=='MM'){ clusts = fuzzy_clust(var_D, distO, dist_type = 1, GS, GM, GQ)}
if(cluster_method=='pMM' || cluster_method=='pMM1' || cluster_method=='pMM2' || cluster_method=='pMM3'){
#if(!distOP_calc){
#distOP = get_dist_OP(GM, ppi_matrix = string, input$CLUSTER_METHOD)
#distOP_calc = TRUE
#rownames(distOP) = colnames(distOP) = GS
#assign('distOP',distOP, envir = .GlobalEnv)
#}
clusts = fuzzy_clust(var_D, distOP, dist_type = 2, GS, GM, GQ)
}
if(cluster_method=='Kappa'){ clusts = fuzzy_clust(var_D, distK, dist_type = 3, GS, GM, GQ)}
assign('clusts',clusts,envir = .GlobalEnv)
v = max(unlist(lapply(clusts,length)))
print(paste('v: ',v))
if(v > 100){
print('too large cluster; distance will adjusted')
var_D = var_D - 0.5
}
if(var_D<0){break}
}
gsinfo = build_clust_info(clusts, GS, GM, GQ)
dtres = build_datatable(gsinfo)
assign('gsinfo', gsinfo, envir = .GlobalEnv)
output$gsinfo = DT::renderDataTable(dtres)
output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
update_input(session, length(unique(gsinfo[,4])))
if(cluster_method=='MM'){ GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distO)}
if(cluster_method=='pMM' || cluster_method=='pMM1' || cluster_method=='pMM2' || cluster_method=='pMM3'){
GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distOP) }
if(cluster_method=='Kappa'){GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distK)}
nodeData = GENESET_NETWORK_OBJ$nodeData
edgeData = GENESET_NETWORK_OBJ$edgeData
color = GENESET_NETWORK_OBJ$color
assign('GENESET_NETWORK_OBJ',GENESET_NETWORK_OBJ,envir = .GlobalEnv)
#GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
output$legend <- renderUI( function_buildlegends(color) )
progress$inc(1/2, detail = "Rendering")
output$plot1 = rcytoscapejs::renderRcytoscapejs({
res = rcytoscapejs(
nodeEntries = GENESET_NETWORK_OBJ$nodes,
edgeEntries = GENESET_NETWORK_OBJ$edges,
layout='cose',
boxSelectionEnabled = FALSE)
return(res)
})
shinyjs::click("AB1")
})
observeEvent(input$DEMO,{
check_data('Human')
progress <- shiny::Progress$new()
on.exit(progress$close())
progress$set(message = "Building", value = 0)
shinyjs::hide(id='Input_box')
shinyjs::show(id='main_panel')
shinyjs::show(id='cluster_row')
shinyjs::hide(id='cluster_message')
progress$inc(1/8, detail = "Reading Geneset File")
infile = list(datapath = 'sample_geneset.txt')
x = readLines(con = infile$datapath)
x = x[-1] # header
GS = c()
GM = list()
GQ = c()
makeReactiveBinding("GS")
makeReactiveBinding("GM")
makeReactiveBinding("GQ")
for(i in 1:length(x)){
temp = strsplit(x[i],'\t')[[1]]
if(as.numeric(temp[3])>input$GENESET_CUTOFF){next}
GS[i] = temp[1]
GM[[i]] = strsplit(temp[2],' ')[[1]]
GQ[i] = as.numeric(temp[3])
}
progress$inc(1/8, detail = "Reading Genescore File")
infile = list(datapath='sample_genescore.txt')
x = readLines(con = infile$datapath)
x = x[-1]
gene_colors = build_gene_colorlist(x)
assign('gene_colors',gene_colors,envir = .GlobalEnv)
gene_score_filter = build_genescore_filter(x)
assign('gene_score_filter',gene_score_filter,envir = .GlobalEnv)
GS <<- GS
GM <<- GM
GQ <<- GQ
progress$inc(1/8, detail = "Calculate MM")
distO = get_dist_O(GM)
rownames(distO) = colnames(distO) = GS
assign('distO',distO, envir = .GlobalEnv)
assign('GM',GM,envir = .GlobalEnv)
progress$inc(1/8, detail = "Calculate pMM")
distOP = get_dist_OP(GM, ppi_matrix = string, input$CLUSTER_METHOD)
rownames(distOP) = colnames(distOP) = GS
assign('distOP',distOP, envir = .GlobalEnv)
progress$inc(1/8, detail = "Calculate Kappa")
distK = get_dist_K(GM)
rownames(distK) = colnames(distK) = GS
assign('distK',distK, envir = .GlobalEnv)
progress$inc(1/8, detail = "Clustering")
var_D = input$CLUSTER_MIN_DISTANCE
clusts = fuzzy_clust(var_D, distOP, dist_type = 2, GS, GM, GQ)
clusts <<- clusts
assign('clusts',clusts,envir = .GlobalEnv)
gsinfo = build_clust_info(clusts, GS, GM, GQ)
assign('gsinfo', gsinfo, envir = .GlobalEnv)
dtres = build_datatable(gsinfo)
output$gsinfo = DT::renderDataTable(dtres)
output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
update_input(session, length(unique(gsinfo[,4])))
update_input2(session, length(unique(gsinfo[,4])))
progress$inc(1/8, detail = "Rendering Network")
GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distOP)
nodeData = GENESET_NETWORK_OBJ$nodeData
edgeData = GENESET_NETWORK_OBJ$edgeData
color = GENESET_NETWORK_OBJ$color
output$legend = renderUI( function_buildlegends(color) )
assign('GENESET_NETWORK_OBJ',GENESET_NETWORK_OBJ,envir = .GlobalEnv)
#GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
#GNO2 = GENESET_NETWORK_OBJ
GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
output$plot1 = rcytoscapejs::renderRcytoscapejs({
res = rcytoscapejs(
nodeEntries = GENESET_NETWORK_OBJ$nodes,
edgeEntries = GENESET_NETWORK_OBJ$edges,
layout='cose',
boxSelectionEnabled = FALSE)
return(res)
})
output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
progress$inc(1/8, detail = "Wait for rendered Network")
#NodeSearch = function(){
#fluidRow( style = {'position:absolute;margin-left:7%;z-index:999'},textInput('FIT','Gene-set search') )
#}
updateSelectizeInput(session, "FIT", choices = unique(gsinfo[,1]), server = TRUE)
shinyjs::click('AB1')
})
observeEvent(input$RUN, {
check_data(input$INPUT_SPECIES)
progress <- shiny::Progress$new()
on.exit(progress$close())
progress$set(message = "Building", value = 0)
shinyjs::hide(id='Input_box')
shinyjs::show(id='main_panel')
shinyjs::show(id='cluster_row')
shinyjs::hide(id='cluster_message')
progress$inc(1/8, detail = "Reading Geneset File")
GS = c()
GM = list()
GQ = c()
makeReactiveBinding("GS")
makeReactiveBinding("GM")
makeReactiveBinding("GQ")
infile = input$INPUT_GENESET_FILE
if(is.null(infile)){
showNotification("INPUT FILE NOT GIVEN", type = 'error')
shinyjs::show(id='Input_box')
shinyjs::hide(id='main_panel')
shinyjs::hide(id='cluster_row')
shinyjs::show(id='cluster_message')
return(NULL)
}
x = readLines(con = infile$datapath)
x = x[-1] # remove header
for(i in 1:length(x)){
temp = strsplit(x[i],'\t')[[1]]
if(as.numeric(temp[3])>input$GENESET_CUTOFF){next}
GS[i] = temp[1]
GM[[i]] = strsplit(temp[2],' ')[[1]]
GQ[i] = as.numeric(temp[3])
}
progress$inc(1/8, detail = "Reading Genescore File")
infile = input$INPUT_GENESCORE_FILE
if(!is.null(infile)){
x = readLines(con = infile$datapath)
x = x[-1]
gene_colors = build_gene_colorlist(x)
assign('gene_colors',gene_colors,envir = .GlobalEnv)
gene_score_filter = build_genescore_filter(x)
assign('gene_score_filter',gene_score_filter,envir = .GlobalEnv)
}
SIGGENE_ONLY = input$WORKING_GENE
if(SIGGENE_ONLY){
for(i in 1:length(GM)){
GM[[i]] = intersect(GM[[i]], gene_score_filter)
}
}
assign('GM',GM, envir = .GlobalEnv)
# ENSEMBL GENESET
if(length(grep('ENS',GM[[1]][1]))!=0){
for(i in 1:length(GM)){ GM[[i]] = unlist(toupper(ent_sym[unlist(ensg_ent[GM[[i]]],use.names = FALSE)]),use.names = FALSE) }
}
# ENSEMBL GENESCORE
if(length(grep('ENS',gene_score_filter[1]))!=0){
for(i in length(gene_score_filter):1){
a = ensg_ent[[gene_score_filter[i]]]
if(length(a)>1){a = a[1]}
a = toupper(ent_sym[[a]])
if(is.null(a)){gene_score_filter = gene_score_filter[-i]; gene_colors = gene_colors[-i]; next}
gene_score_filter[i] = a
}
names(gene_colors) = gene_score_filter
}
# ENTREZ GENESET
if(!is.na(as.numeric(GM[[1]][1]))){
for(i in 1:length(GM)){GM[[i]] = unlist(toupper(ent_sym[GM[[i]]]), use.names = FALSE)}
}
# ENTREZ GENESCORE
if(!is.na(as.numeric(gene_score_filter[1]))){
for(i in length(gene_score_filter):1){
a = toupper(ent_sym[[gene_score_filter[i]]])
if(is.null(a)){gene_score_filter = gene_score_filter[-i]; gene_colors = gene_colors[-i]; next}
gene_score_filter[i] = a
}
names(gene_colors) = gene_score_filter
}
GS = GS[which(lapply(GM, length)!=0)]
GQ = GQ[which(lapply(GM, length)!=0)]
GM = GM[which(lapply(GM, length)!=0)]
GS <<- GS
GM <<- GM
GQ <<- GQ
progress$inc(1/8, detail = "Calculate MM")
distO = get_dist_O(GM)
rownames(distO) = colnames(distO) = GS
assign('distO',distO, envir = .GlobalEnv)
progress$inc(1/8, detail = "Calculate pMM")
distOP = get_dist_OP(GM, ppi_matrix = string, input$CLUSTER_METHOD)
rownames(distOP) = colnames(distOP) = GS
assign('distOP',distOP, envir = .GlobalEnv)
progress$inc(1/8, detail = "Calculate Kappa")
distK = get_dist_K(GM)
rownames(distK) = colnames(distK) = GS
assign('distK',distK, envir = .GlobalEnv)
progress$inc(1/8, detail = "Clustering")
var_D = input$CLUSTER_MIN_DISTANCE
clusts = fuzzy_clust(var_D, distOP, dist_type = 2, GS, GM, GQ)
clusts <<- clusts
gsinfo = build_clust_info(clusts, GS, GM, GQ)
assign('gsinfo', gsinfo, envir = .GlobalEnv)
dtres = build_datatable(gsinfo)
output$gsinfo = DT::renderDataTable(dtres)
output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
update_input(session, length(unique(gsinfo[,4])))
update_input2(session, length(unique(gsinfo[,4])))
progress$inc(1/8, detail = "Rendering Network")
GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distOP)
nodeData = GENESET_NETWORK_OBJ$nodeData
edgeData = GENESET_NETWORK_OBJ$edgeData
color = GENESET_NETWORK_OBJ$color
output$legend = renderUI( function_buildlegends(color) )
assign('GENESET_NETWORK_OBJ',GENESET_NETWORK_OBJ,envir = .GlobalEnv)
GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
#GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData, edgeTargetShape = 'none',nodeLabelColor = 'black')
GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
#rcytoscapejs(gno4$nodes, gno4$edges, layout='cose',boxSelectionEnabled = FALSE, width = 1000, height = 1000)
output$plot1 = rcytoscapejs::renderRcytoscapejs({
res = rcytoscapejs(
nodeEntries = GENESET_NETWORK_OBJ$nodes,
edgeEntries = GENESET_NETWORK_OBJ$edges,
layout='cose',
boxSelectionEnabled = FALSE)
return(res)
})
output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
progress$inc(1/8, detail = "Wait for rendered Network")
updateSelectizeInput(session, "FIT", choices = unique(gsinfo[,1]), server = TRUE)
shinyjs::click("AB1")
})
observeEvent(input$DEGREE, {
degrees = find_degree(GENE_NETWORK_OBJ)
tt = degrees[sort(which(rank(-degrees, ties.method = 'min')<=input$DEGREE_CUTOFF), decreasing = TRUE)]
hub_table = data.frame(matrix(ncol=2,nrow=0))
colnames(hub_table) = c("GENE","LINKS")
for(i in 1:length(tt)){ hub_table[i,] = c(names(tt)[i], tt[i]) }
output$DEGREE_OUTPUT = DT::renderDataTable(hub_table, options= list(autoWidth=TRUE,bFilter=FALSE),rownames = FALSE)
})
observeEvent(input$CHECK,{
clust_obj = clusts
res = c()
for(i in 1:length(clust_obj)){
this_clust = clust_obj[[i]]
this_clust_genes = unique(unlist(GM[this_clust]))
this_clust_genes = intersect(this_clust_genes, gene_score_filter)
if(length(this_clust_genes)<=1){next}
GENE_NETWORK_OBJ = build_genenetwork(
genes = this_clust_genes,
ppi_cutoff = input$PPI_CUTOFF/1000,
ppi_matrix = string,
multiEdge = FALSE,
showError = FALSE
)
degrees = find_degree(GENE_NETWORK_OBJ)
tt = degrees[sort(which(rank(-degrees, ties.method = 'min')<=input$RANK_CUTOFF), decreasing = TRUE)]
if(is.null(names(degrees))){next}
clust_no = rep(i,length(tt))
gene = names(tt)
names(tt) = NULL
degree = tt
res = rbind(res,data.frame(cbind(gene, degree, clust_no), stringsAsFactors = FALSE))
}
if(nrow(res)==0){
showNotification("NO GENES WITH DEGREE CUTOFF", type = 'error')
return()
}
k = sort(unique(res[which(duplicated(res['gene'])),'gene']))
if(length(k)==0){
showNotification("NO HUBS WITH DEGREE CUTOFF", type = 'error')
return()
}
kk = c()
for(i in 1:length(k)){ kk = c(kk, which(res['gene']==k[i])) }
output$HUB_TABLE = renderTable(res[kk,])
})
}
shinyApp(ui = ui(), server = server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.