server.R 64.3 KB
Newer Older
1
source('LoadPackages.R')
2
library(plotly)
svolant's avatar
svolant committed
3

stevenn's avatar
stevenn committed
4
shinyServer(function(input, output,session) {
svolant's avatar
svolant committed
5
6
7

  hide(id = "loading-content", anim = TRUE, animType = "fade",time=1.5)
  hide(id = "loading-content-bar", anim = TRUE, animType = "fade",time=1.5)
8
9
10
11
12
  #####################################################
  ##
  ##                    LOAD FILES
  ##
  #####################################################
stevenn's avatar
stevenn committed
13
  
stevenn's avatar
stevenn committed
14
15
  ## Create base for contrast
  rand = floor(runif(1,0,1e9))
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
16
  namesfile = tempfile(pattern = "BaseContrast", tmpdir = tempdir(), fileext = "")
stevenn's avatar
stevenn committed
17
  file.create(namesfile,showWarnings=FALSE)
18
  
svolant's avatar
svolant committed
19
  ## Popup messages
svolant's avatar
svolant committed
20
  observe(if(input$AddRegScatter) info("By adding the regression line, you will lose interactivity."))
21
  
svolant's avatar
svolant committed
22

stevenn's avatar
stevenn committed
23
  ## Counts file
stevenn's avatar
stevenn committed
24
  dataInputCounts <-reactive({ 
25
    
stevenn's avatar
stevenn committed
26
    inFile <- input$fileCounts
27
    
stevenn's avatar
stevenn committed
28
    if (is.null(inFile)) return(NULL)
29
    
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
30
    data = read.csv(inFile$datapath,sep=input$sepcount,header=TRUE,check.names=FALSE)
svolant's avatar
svolant committed
31
    colnames(data) = gsub("-",".",colnames(data))
32
    
stevenn's avatar
stevenn committed
33
    ## Rownames
Stevenn Volant's avatar
Stevenn Volant committed
34
    if(!TRUE%in%duplicated(data[,1])) rownames(data)=data[,1];data=data[,-1]
35
    
stevenn's avatar
stevenn committed
36
37
38
    return(as.data.frame(data))
  })
  
39
40
  
  
stevenn's avatar
stevenn committed
41
42
  ## Taxo File
  dataInputTaxo <-reactive({ 
stevenn's avatar
stevenn committed
43
    
stevenn's avatar
stevenn committed
44
    inFile <- input$fileTaxo
stevenn's avatar
stevenn committed
45
    
stevenn's avatar
stevenn committed
46
    if (is.null(inFile)) return(NULL)
47
    
Stevenn Volant's avatar
Stevenn Volant committed
48
49
    if(input$TypeTaxo=="Table") 
    {
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
50
      data = read.csv(inFile$datapath,sep=input$septaxo,header=TRUE)
svolant's avatar
svolant committed
51
      
Stevenn Volant's avatar
Stevenn Volant committed
52
      ## Rownames
svolant's avatar
svolant committed
53
54
55
56
57
58
      if(!TRUE%in%duplicated(data[,1])){ 
        DataNames=data[,1]
        colNames=colnames(data)[-1]
        data=as.matrix(data[,-1])
        rownames(data)=DataNames
        colnames(data) = colNames
59
      }
Stevenn Volant's avatar
Stevenn Volant committed
60
    }
stevenn's avatar
stevenn committed
61
    
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
62
63
    if(input$TypeTaxo=="RDP") 
    {
Stevenn Volant's avatar
Stevenn Volant committed
64
      data = read_rdp(inFile$datapath,input$RDP_th)
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
65
    }
stevenn's avatar
stevenn committed
66
67
68
    
    ## Add NA
    data=as.matrix(data)
Stevenn Volant's avatar
Stevenn Volant committed
69
    indNa = which(data=="")
stevenn's avatar
stevenn committed
70
71
    data[indNa]=NA
    
stevenn's avatar
stevenn committed
72
    return(as.data.frame(data))
stevenn's avatar
stevenn committed
73
  })
74
75
  
  
stevenn's avatar
stevenn committed
76
77
  ## BIOM File
  dataInputBiom <-reactive({ 
stevenn's avatar
stevenn committed
78
    
stevenn's avatar
stevenn committed
79
    inFile <- input$fileBiom
stevenn's avatar
stevenn committed
80
    
stevenn's avatar
stevenn committed
81
    if (is.null(inFile)) return(NULL)
stevenn's avatar
stevenn committed
82
    data = read_biom(inFile$datapath)
stevenn's avatar
stevenn committed
83
    
stevenn's avatar
stevenn committed
84
    return(data)
stevenn's avatar
stevenn committed
85
  })
86
87
88
  
  
  
stevenn's avatar
stevenn committed
89
90
  ## Input data
  dataInput <-reactive({ 
stevenn's avatar
stevenn committed
91
    
stevenn's avatar
stevenn committed
92
    data = NULL
Stevenn Volant's avatar
Stevenn Volant committed
93
94
    check = NULL
    percent = NULL
stevenn's avatar
stevenn committed
95
    
stevenn's avatar
stevenn committed
96
    if(input$FileFormat=="fileCounts")
stevenn's avatar
stevenn committed
97
    {
stevenn's avatar
stevenn committed
98
99
      Counts = dataInputCounts()
      Taxo = dataInputTaxo()
Stevenn Volant's avatar
Stevenn Volant committed
100
101
102
103
104
105
106
      if(!is.null(Counts) && !is.null(Taxo))
      { 
        tmp = GetDataFromCT(Counts,Taxo)
        data = list(counts=tmp$counts,taxo=tmp$taxo)
        check = list(CheckCounts=tmp$CheckCounts,CheckTaxo=tmp$CheckTaxo,CheckPercent=tmp$CheckPercent)
        percent = tmp$Percent
      }    
stevenn's avatar
stevenn committed
107
108
    }
    
stevenn's avatar
stevenn committed
109
    if(input$FileFormat=="fileBiom")
stevenn's avatar
stevenn committed
110
    {
stevenn's avatar
stevenn committed
111
      tmpBIOM = dataInputBiom()
Stevenn Volant's avatar
Stevenn Volant committed
112
113
114
115
116
117
118
      if(!is.null(tmpBIOM))
      {
        tmp = GetDataFromBIOM(tmpBIOM)
        data = list(counts=tmp$counts,taxo=tmp$taxo)
        check = list(CheckCounts=tmp$CheckCounts,CheckTaxo=tmp$CheckTaxo,CheckPercent=tmp$CheckPercent)
        percent = tmp$Percent
      }
stevenn's avatar
stevenn committed
119
120
    }
    
Stevenn Volant's avatar
Stevenn Volant committed
121
    return(list(data=data,check=check,percent=percent))
stevenn's avatar
stevenn committed
122
123
124
  })
  
  
125
  
126
127
128
129
130
131
132
133
134
  
  
  ## Size factor file (optional)
  dataSizeFactors <-reactive({ 
    
    inFile <- input$fileSizeFactors
    
    if (is.null(inFile)) return(NULL)
    
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
135
    data = read.csv(inFile$datapath,sep=input$sepsize,header=TRUE)
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    return(as.data.frame(data))
  })
  
  
  ## Size factor file (optional)
  SizeFactors_fromFile <-reactive({ 
    
    Error = NULL
    Check = TRUE
    
    data = dataSizeFactors()
    normFactors = dataMergeCounts()$normFactors
    
    if(!is.null(data)){
      ## Check the format
      
      tmp = as.numeric(data)
      names(tmp) = colnames(data)
      
      if(length(tmp)!=length(normFactors)){Error = "The number of samples is not the same than in the target file, size factors will be estimated"; Check = FALSE}
      if(!identical(names(tmp),names(normFactors))){Error = "The names are not the same or in the same order than in the target file, size factors will be estimated"; Check = FALSE}
157
      
158
159
160
161
162
163
164
165
166
167
168
      if(Check) normFactors = tmp
    }
    
    return(list(Check = Check,Error = Error,normFactors=normFactors))
  })
  
  
  
  
  
  
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
169
  ## Merge counts data
170
  dataMergeCounts <-reactive({
Stevenn Volant's avatar
Stevenn Volant committed
171
    input$RunDESeq
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
172
173
174
    
    counts = NULL
    CheckTarget = FALSE
175
    normFactors = NULL
Stevenn Volant's avatar
Stevenn Volant committed
176
    CT_noNorm = NULL
177
    CT_Norm = NULL
178
    #labeled= NULL
179
    data = isolate(dataInput()$data)
180
    target = isolate(dataInputTarget()$target)
181
    taxo = isolate(input$TaxoSelect)
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
182
    
183
    withProgress(
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
184
185
    if(!is.null(data$counts) && !is.null(data$taxo) && nrow(data$counts)>0 && nrow(data$taxo)>0 && !is.null(taxo) && taxo!="..." && !is.null(target)) 
    {
186
187
      design = GetDesign(isolate(input))
      tmp = isolate(GetCountsMerge(input,data,taxo,target,design))
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
188
      counts = tmp$counts
189
190
191
192
193
194
195
196
      
      ## Filtering the counts
      if(isolate(input$AddFilter) && !is.null(isolate(input$SliderThSamp)) && !is.null(isolate(input$SliderThAb)))
      {
        ind.filter =Filtered_feature(counts,isolate(input$SliderThSamp),isolate(input$SliderThAb))$ind
        counts = counts[-ind.filter,]
      }
      
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
197
      CheckTarget = tmp$CheckTarget
198
199
      #target = tmp$target
      #labeled = tmp$labeled
200
      normFactors = tmp$normFactors
201
202
      
      ## OTU table, norm and no norm
Stevenn Volant's avatar
Stevenn Volant committed
203
      CT_noNorm = tmp$CT_noNorm
204
      CT_Norm = tmp$CT_Norm
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
205
    }
206
    ,message="Merging the counts ...")
207
    return(list(counts=counts,CheckTarget=CheckTarget,normFactors=normFactors,CT_noNorm=CT_noNorm, CT_Norm=CT_Norm))
208
    #return(list(counts=counts,target=target,labeled=labeled,normFactors=normFactors,CT_noNorm=CT_noNorm))
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
209
  })
210
211
  
  
Stevenn Volant's avatar
Stevenn Volant committed
212
213
214
215
216
217
218
  # Infobox Error counts
  output$InfoErrorCounts <- renderInfoBox({
    
    tmp = dataInput()
    data = tmp$data
    check = tmp$check
    cond = (!is.null(data$counts) && nrow(data$counts)>0)
219
    res =infoBox(h6(strong("Count table")), subtitle = h6("Load the count table") ,color = "light-blue",width=NULL,fill=TRUE, icon = icon("upload"))
Stevenn Volant's avatar
Stevenn Volant committed
220
221
222
    
    if(cond)
    {
223
224
225
      if(!is.null(check$CheckCounts$Warning)) res = infoBox(h6(strong("Count table")), subtitle = h6(check$CheckCounts$Warning), icon = icon("warning"),color = "orange",width=NULL,fill=TRUE)
      if(!is.null(check$CheckCounts$Error)) res = infoBox(h6(strong("Count table")), subtitle = h6(check$CheckCounts$Error), icon = icon("thumbs-o-down"),color = "red",width=NULL,fill=TRUE)
      if(is.null(check$CheckCounts$Error) && is.null(check$CheckCounts$Warning)) res = infoBox(h6(strong("Count table")), subtitle = h6(paste("Format of the count table seems to be OK")), icon = icon("thumbs-o-up"),color = "green",width=NULL,fill=TRUE)
Stevenn Volant's avatar
Stevenn Volant committed
226
227
228
229
    }
    
    return(res)
  })
230
  
Stevenn Volant's avatar
Stevenn Volant committed
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  # Infobox Error counts
  output$InfoErrorTaxo <- renderInfoBox({
    
    tmp = dataInput()
    data = tmp$data
    check = tmp$check
    cond = (!is.null(data$taxo) && nrow(data$taxo)>0)
    res =infoBox(h6(strong("Taxonomy table")), subtitle = h6("Load the taxonomy table") ,color = "light-blue",width=NULL,fill=TRUE, icon = icon("upload"))
    
    if(cond)
    {
      if(!is.null(check$CheckTaxo$Warning)) res = infoBox(h6(strong("Taxonomy table")), subtitle = h6(check$CheckTaxo$Warning), icon = icon("warning"),color = "orange",width=NULL,fill=TRUE)
      if(!is.null(check$CheckTaxo$Error)) res = infoBox(h6(strong("Taxonomy table")), subtitle = h6(check$CheckTaxo$Error), icon = icon("thumbs-o-down"),color = "red",width=NULL,fill=TRUE)
      if(is.null(check$CheckTaxo$Error) && is.null(check$CheckTaxo$Warning)) res = infoBox(h6(strong("Taxonomy table")), subtitle = h6(paste("Format of the taxonomy table seems to be OK")), icon = icon("thumbs-o-up"),color = "green",width=NULL,fill=TRUE)
    }
    
    return(res)
  })
249
250
  
  
Stevenn Volant's avatar
Stevenn Volant committed
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  # Infobox Error counts
  output$valueErrorPercent <- renderInfoBox({
    
    tmp = dataInput()
    data = tmp$data
    check = tmp$check
    cond = (!is.null(data$counts) && nrow(data$counts)>0 && !is.null(data$taxo) && nrow(data$taxo)>0)
    res = valueBox(paste0(0, "%"),h6(strong("Annotated features")), color = "light-blue",width=NULL,icon = icon("list"))
    
    if(cond)
    {
      percent = round(100*tmp$percent,2)
      if(percent==0) res = valueBox(paste0(percent, "%"),h6(strong("Annotated features")), color = "red",width=NULL,icon = icon("list"))  
      if(percent!=0) res = valueBox(paste0(percent, "%"),h6(strong("Annotated features")), color = "green",width=NULL,icon = icon("list"))  
      
    }
    
    return(res)
  })
stevenn's avatar
stevenn committed
270
  
271
  
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  ####### Filtering the counts (sliders)
  
  output$ThAb <- renderUI({
    input$AddFilter
    
    res = NULL
    counts = isolate(dataMergeCounts()$counts)
    tot = rowSums(counts)
    tmp = SelectThreshAb(counts,lambda=max(round(sum(counts)/nrow(counts)*0.05),min(tot)+1),graph=FALSE)
    
    res = sliderInput("SliderThAb","Threshold on the total abundance (in log)",min=0,max=round(max(log(tot+1)),1),value = log(tmp+1))
    return(res)
  })
  
  
  output$ThSamp <- renderUI({
    input$AddFilter
    
    res = NULL
    counts = isolate(dataMergeCounts()$counts)
    counts.bin = as.matrix(counts)
    counts.bin[which(counts>0)] = 1
    nbSampByFeat = rowSums(counts.bin)
    
    ## Default value
    val = round(max(nbSampByFeat)*0.2)
    
    res = sliderInput("SliderThSamp","Threshold on the minimal number of samples",min=0,max=max(nbSampByFeat),value = val)
    return(res)
  })
  
  
  ## Plot for the filtering step$
  
  # plot_filter(counts,th.samp,th.abund,type="Scatter")
  
  output$Plot_ThAb <- renderPlotly({
    counts = dataMergeCounts()$counts
    ## output of plot_filter is ggplot class
    plot_filter(counts,input$SliderThSamp,input$SliderThAb,type="Abundance")
    
  })
    
  output$Plot_ThSamp <- renderPlotly({
    counts = dataMergeCounts()$counts
    ## output of plot_filter is ggplot class
    plot_filter(counts,input$SliderThSamp,input$SliderThAb,type="Samples")
  })
320
  
321
322
323
324
325
  output$Plot_Scatter_Filter <- renderScatterD3({
    counts = dataMergeCounts()$counts
    ## output of plot_filter is ggplot class
    plot_filter(counts,input$SliderThSamp,input$SliderThAb,type="Scatter")
  })
326
327
328
329
330
  #####################################################
  ##
  ##                DYNAMIC MENU
  ##
  #####################################################
stevenn's avatar
stevenn committed
331
332
333
334
335
  
  
  
  output$dymMenu <- renderMenu({
    
Stevenn Volant's avatar
Stevenn Volant committed
336
337
338
    tmp = dataInput()
    data = tmp$data
    check = tmp$check
stevenn's avatar
stevenn committed
339
    
Stevenn Volant's avatar
Stevenn Volant committed
340
341
    ## Check error in the counts and taxonomy table 
    CheckOK = (is.null(check$CheckCounts$Error) && is.null(check$CheckTaxo$Error)  && is.null(check$CheckPercent))
342
    
Stevenn Volant's avatar
Stevenn Volant committed
343
    if(!is.null(data$counts) && !is.null(data$taxo) && nrow(data$counts)>0 && nrow(data$taxo)>0 && CheckOK)
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
344
    {
svolant's avatar
svolant committed
345

svolant's avatar
svolant committed
346
      sidebarMenu(id = "side",
stevenn's avatar
stevenn committed
347
348
        menuItem("Statistical analysis",
                 menuSubItem("Run differential analysis",tabName="RunDiff"),
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
349
                 menuSubItem("Diagnostic plots",tabName="DiagPlotTab"),
stevenn's avatar
stevenn committed
350
                 menuSubItem("Tables",tabName="TableDiff"),
351
352
                 icon = icon("bar-chart-o"), tabName = "AnaStat"
        ),
353
354
355
356
        menuItem("Visualization",icon = icon("area-chart"),
                 menuSubItem("Global views",tabName="GlobVisu"),
                 menuSubItem("Comparison plots",tabName="CompPlot"),
                 tabName = "Visu"),
Stevenn Volant's avatar
Stevenn Volant committed
357
        menuItem("Perspective plots", icon = icon("pie-chart"), tabName = "Krona")
stevenn's avatar
stevenn committed
358
      )
359
    }
svolant's avatar
svolant committed
360

stevenn's avatar
stevenn committed
361
362
363
  })
  
  
364
  
stevenn's avatar
stevenn committed
365
366
367
368
369
370
371
  #####################################################
  ##
  ##                DATA TABLE
  ##
  #####################################################
  
  ## Counts Table
372
  output$DataCounts <- DT::renderDataTable(
Stevenn Volant's avatar
Stevenn Volant committed
373
    dataInput()$data$counts, 
stevenn's avatar
stevenn committed
374
    options = list(lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
375
                   pageLength = 10,scrollX=TRUE, processing=FALSE
stevenn's avatar
stevenn committed
376
377
    ))
  
378
  ## Counts Table
379
380
381
382
383
384
385
  output$DataVenn<- DT::renderDataTable(#{
    #SelContrast = input$ContrastList_table_FC
    #resDiff = ResDiffAnal()
    #BaseContrast = read.table(namesfile,header=TRUE)
    GetData_venn(input,input$ContrastList_table_FC,read.table(namesfile,header=TRUE),ResDiffAnal())$df.tot,
  #}
   options = list(lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
386
                    pageLength = 10,scrollX=TRUE, processing=FALSE
387
  ))
388
389
  
  
stevenn's avatar
stevenn committed
390
  ## Taxonomy table
391
  output$DataTaxo <- DT::renderDataTable(
Stevenn Volant's avatar
Stevenn Volant committed
392
    dataInput()$data$taxo, 
stevenn's avatar
stevenn committed
393
    options = list(lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
svolant's avatar
svolant committed
394
                   pageLength = 10,scrollX=TRUE, processing=FALSE
stevenn's avatar
stevenn committed
395
    ))
396
  
stevenn's avatar
stevenn committed
397
  
stevenn's avatar
stevenn committed
398
  ## Tab box for data visualisation
stevenn's avatar
stevenn committed
399
400
  output$TabBoxData <- renderUI({
    
Stevenn Volant's avatar
Stevenn Volant committed
401
    data=dataInput()$data
stevenn's avatar
stevenn committed
402
403
404
    
    if(!is.null(data$counts) && !is.null(data$taxo) && nrow(data$counts)>0 && nrow(data$taxo)>0)
    {
405
      tabBox(width = NULL, selected = "Count table",
406
407
             tabPanel("Count table",DT::dataTableOutput("DataCounts")),
             tabPanel("Taxonomy",DT::dataTableOutput("DataTaxo")),
svolant's avatar
svolant committed
408
409
             tabPanel("Summary",h5(strong("Percentage of annotation")),htmlOutput("SummaryView"),
                      br(),h5(strong("Number of features by level:")),plotOutput("SummaryViewBarplot",width = 1200,height=500))
stevenn's avatar
stevenn committed
410
      )
stevenn's avatar
stevenn committed
411
    }
stevenn's avatar
stevenn committed
412
    
stevenn's avatar
stevenn committed
413
  })
414
  
svolant's avatar
svolant committed
415
416
417
418
419
420
421
  output$SummaryView <- renderGvis({
    data = dataInput()$data
    taxo = data$taxo
    counts = data$counts
    res = NULL
    if(!is.null(data$counts) && !is.null(data$taxo) && nrow(data$counts)>0 && nrow(data$taxo)>0)
    {
svolant's avatar
svolant committed
422
      taxo = rbind(taxo,rep(NA,ncol(taxo)))
423
      tmpPercent = round(apply(is.na(taxo),2,table)["FALSE",]/(nrow(taxo)-1)*100,2)
424
      
425
      #print(tmpPercent)
svolant's avatar
svolant committed
426
      df <- data.frame(Label = colnames(taxo),Value = tmpPercent)
427
      
svolant's avatar
svolant committed
428
      res = gvisGauge(df,options=list(min=0, max=100, greenFrom=80,
429
430
                                      greenTo=100, yellowFrom=60, yellowTo=80,
                                      redFrom=0, redTo=60, width=1200, height=300))
svolant's avatar
svolant committed
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
    }
    return(res)
  })
  
  
  output$SummaryViewBarplot <- renderPlot({
    data = dataInput()$data
    taxo = data$taxo
    counts = data$counts
    res = NULL
    if(!is.null(data$counts) && !is.null(data$taxo) && nrow(data$counts)>0 && nrow(data$taxo)>0)
    {
      colors=rep(c("#1f77b4","#aec7e8","#ff7f0e","#ffbb78", "#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b",
                   "#c49c94","#e377c2","#f7b6d2","#7f7f7f", "#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"),ceiling(ncol(taxo)/20))
      tmp = apply(taxo,2,unique)
      nbfeatures = as.numeric(lapply(tmp,length)) -as.numeric(lapply(lapply(tmp,is.na),any))
      df <- data.frame(Label = colnames(taxo),Count = nbfeatures)
      df$Label = factor(df$Label,levels =colnames(taxo) )
      res = ggplot(df,aes(x=Label,y=Count,fill=Label))+geom_bar(stat="identity")
      res = res + theme_bw() + xlab("Taxonomy") + scale_fill_manual(values=colors) + guides(fill=FALSE)
    }
    return(res)
  })
  
stevenn's avatar
stevenn committed
455
456
457
458
459
  #####################################################
  ##
  ##                TARGET FILE
  ##
  #####################################################
stevenn's avatar
stevenn committed
460
  
461
  
stevenn's avatar
stevenn committed
462
463
464
465
  ## Load target file
  dataInputTarget <-reactive({ 
    
    inFile <- input$fileTarget
Stevenn Volant's avatar
Stevenn Volant committed
466
    counts = dataInput()$data$counts
467
468
    
    
stevenn's avatar
stevenn committed
469
470
471
    if (is.null(inFile)) return(NULL)
    
    
472
    data = read.csv(inFile$datapath,sep=input$septarget,header=TRUE)
svolant's avatar
svolant committed
473
    data = as.data.frame(data)
svolant's avatar
svolant committed
474
    ## Replace "-" by "."
svolant's avatar
svolant committed
475
476
    ind_num = which(sapply(data,is.numeric))
    if(length(ind_num)>0){
svolant's avatar
svolant committed
477
      data_tmp =cbind( as.data.frame(apply(data[,-ind_num],2,gsub,pattern = "-",replacement = ".")),data[,ind_num])
svolant's avatar
svolant committed
478
479
480
      colnames(data_tmp) = c(colnames(data)[-ind_num],colnames(data)[ind_num])
      data = data_tmp
    }
481
    if(length(ind_num)==0){data = as.data.frame(apply(data,2,gsub,pattern = "-",replacement = "."))}
svolant's avatar
svolant committed
482
    
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
483
    rownames(data) <- as.character(data[, 1])
484
    ind = which(rownames(data)%in%colnames(counts))
485
    target = data[ind,]
svolant's avatar
svolant committed
486
487
    
    # target = as.data.frame(apply(target,2,gsub,pattern = "-",replacement = "."))
488
    
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
489
490
491
492
    #ord = order(rownames(data))
    #data = data[ord,]
    ### A SUPPRIMER 
    #rownames(data) <- colnames(counts)
493
494
    
    # Percent annotated
495
496
497
    #     print(ind)
    #     print(colnames(counts))
    #     print(rownames(data))
498
499
    labeled = length(ind)/length(colnames(counts))*100.0
    
500
    return(list(target = target, labeled=labeled))
stevenn's avatar
stevenn committed
501
  })
502
503
504
  
  
  
stevenn's avatar
stevenn committed
505
506
  ## Interest Variables
  output$SelectInterestVar <- renderUI({
507
    
508
    target=dataInputTarget()$target
stevenn's avatar
stevenn committed
509
510
511
    if(!is.null(target)) 
    {
      namesTarget = colnames(target)[2:ncol(target)]
Stevenn Volant's avatar
Stevenn Volant committed
512
      selectInput("InterestVar",h6(strong("Select the variables")),namesTarget,selected=namesTarget,multiple=TRUE)
stevenn's avatar
stevenn committed
513
    }
514
    
stevenn's avatar
stevenn committed
515
  })
516
517
  
  
stevenn's avatar
stevenn committed
518
519
  ## Interactions
  output$SelectInteraction2 <- renderUI({
520
    
521
    target = dataInputTarget()$target
522
    
stevenn's avatar
stevenn committed
523
524
525
526
527
    if(!is.null(target)) 
    {
      Interac = GetInteraction2(target)
      selectInput("Interaction2",h6(strong("Add interactions")),Interac,selected=NULL,multiple=TRUE)
    }
stevenn's avatar
stevenn committed
528
    
stevenn's avatar
stevenn committed
529
530
531
  })


svolant's avatar
svolant committed
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
  ## Var for normalization
  output$SelectVarNorm <- renderUI({
    
    target=dataInputTarget()$target
    res = selectInput("VarNorm",h6(strong("Normalization by:")),NULL,multiple=TRUE)
    if(!is.null(target)) 
    {
      namesTarget = colnames(target)[2:ncol(target)]
      ind = which(apply(as.data.frame(target[,namesTarget]),2,is.numeric))
      if(length(ind)>=1) namesTarget = namesTarget[-ind]
      res = selectInput("VarNorm",h6(strong("Normalization by:")),c(NULL,namesTarget),multiple=TRUE)
    }
    return(res)
    
  })
  
  
  
stevenn's avatar
stevenn committed
550
551
  ## Reference radio buttons
  output$RefSelect <- renderUI({
stevenn's avatar
stevenn committed
552
    
553
    target = dataInputTarget()$target
stevenn's avatar
stevenn committed
554
555
    RB=list()
    if(!is.null(target)) 
stevenn's avatar
stevenn committed
556
    {
stevenn's avatar
stevenn committed
557
558
559
560
      InterVar = input$InterestVar
      if(length(InterVar)>0)
      {
        names = paste0("Ref",InterVar)
561
562
563
564
565
        for(i in 1:length(names))
        {
          val = unique(target[,InterVar[i]])
          RB[[i]] = selectInput(names[i],paste("Reference for",InterVar[i]),as.vector(val))
        }
stevenn's avatar
stevenn committed
566
      }
stevenn's avatar
stevenn committed
567
    }
stevenn's avatar
stevenn committed
568
    return(RB)
stevenn's avatar
stevenn committed
569
    
stevenn's avatar
stevenn committed
570
  })
571
572
  
  
stevenn's avatar
stevenn committed
573
574
  # Infobox design
  output$RowTarget <- renderInfoBox({
575
576
577
578
    #target = dataInputTarget()
    #labeled = dataMergeCounts()$labeled
    labeled = dataInputTarget()$labeled
    if(!is.null(labeled)) 
stevenn's avatar
stevenn committed
579
580
    {
      #### Ajout fontion check target
581
582
583
584
      #infoBox(h6(strong("Target file")), subtitle = h6("Your target file is OK"), icon = icon("thumbs-o-up"),color = "green",width=NULL,fill=TRUE)
      labeled = round(labeled,2)
      if(labeled>0) res = valueBox(paste0(labeled, "%"),h6(strong("Labeled features")), color = "green",width=NULL,icon = icon("list"))
      else res = valueBox(paste0(labeled, "%"),h6(strong("Labeled features")), color = "red",width=NULL,icon = icon("list"))  
stevenn's avatar
stevenn committed
585
    }
586
587
588
589
590
    #else infoBox(h6(strong("Target file")), subtitle = h6("Label of the target file must correspond to count table column names") ,color = "light-blue",width=NULL,fill=TRUE, icon = icon("warning"))
    else res = valueBox(paste0(0, "%"),h6(strong("Labeled features")), color = "light-blue",width=NULL,icon = icon("list"))
    return(res)
  }
  )
591
592
593
594
  
  
  
  
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
595
  ## target table
596
  output$DataTarget <- DT::renderDataTable(
597
598
    dataInputTarget()$target,
    options = list(lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
599
                   pageLength = 10,scrollX=TRUE, processing=FALSE
600
601
    ))
  
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
602
  ## Counts table for the selected taxonomy level
603
  output$CountsMerge <- DT::renderDataTable(
604
    round(counts(ResDiffAnal()$dds,normalized=TRUE)),
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
605
    options = list(lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
606
                   pageLength = 10,scrollX=TRUE, processing=FALSE
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
607
    ))
608
609
  
  
Stevenn Volant's avatar
Stevenn Volant committed
610
  ## Box for merged counts
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
611
  output$BoxCountsMerge <- renderUI({
612
613
    input$RunDESeq
    counts = isolate(dataMergeCounts()$counts)
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
614
615
616
617
    taxo = input$TaxoSelect
    
    if(!is.null(counts) && taxo != "...")
    {
618
      box(title=paste("Count table (",taxo,")",sep=""),width = NULL, status = "primary", solidHeader = TRUE,collapsible = TRUE,collapsed = TRUE,
619
          DT::dataTableOutput("CountsMerge"),
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
620
621
622
623
624
625
          downloadButton('ExportCounts', 'Export normalised counts'),
          downloadButton('ExportRelative', 'Export relative abundance')
      )  
    }
    
  })
626
  
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
627
628
  ## Export in .csv
  output$ExportCounts <- downloadHandler(
Stevenn Volant's avatar
Stevenn Volant committed
629
630
    filename = function() { 'NormCounts.csv' },
    content = function(file){write.csv(dataMergeCounts()$counts, file)}
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
631
  )
632
  
stevenn's avatar
stevenn committed
633
634
635
  ## Export in .csv
  output$ExportRelative <- downloadHandler(
    filename = function() { 'RelativeAb.csv' },
Stevenn Volant's avatar
Stevenn Volant committed
636
    content = function(file){write.csv(dataMergeCounts()$counts/colSums(dataMergeCounts()$counts), file)}
stevenn's avatar
stevenn committed
637
  )
638
  
639
640
  ## Export size factors
  output$ExportSizeFactor <- downloadHandler(
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
641
642
    filename = function() { if (input$sepsizef == "\t") 'SHAMAN_sizefactors.tsv' else 'SHAMAN_sizefactors.csv' },
    content = function(file){write.table(SizeFactor_table(), file,quote=FALSE,row.names = FALSE,sep=input$sepsizef)}
643
644
645
  )
  
  
stevenn's avatar
stevenn committed
646
647
648
  ## Box for target visualisation
  output$BoxTarget <- renderUI({
    
649
    target = dataInputTarget()$target
650
    
stevenn's avatar
stevenn committed
651
652
653
    if(!is.null(target) &&  nrow(target)>0)
    {
      box(title="Target file overview",width = NULL, status = "primary", solidHeader = TRUE,collapsible = TRUE,collapsed = TRUE,
654
          DT::dataTableOutput("DataTarget")
stevenn's avatar
stevenn committed
655
656
657
658
      )  
    }
    
  })
659
660
661
662
663
664
665
666
  
  
  
  #####################################################
  ##
  ##            DEFINE CONTRAST
  ##
  #####################################################
stevenn's avatar
stevenn committed
667
668
669
  
  output$contrastMat <- renderUI({
    
stevenn's avatar
stevenn committed
670
671
672
    resDiff = ResDiffAnal()
    dds = resDiff$dds
    names = resultsNames(dds)
673
    
stevenn's avatar
stevenn committed
674
675
    Contrast=list()
    
676
    for(i in 1:length(names)){Contrast[[i]] = numericInput(names[i],names[i],0,step=1,min=-1,max=1)}
677
    
stevenn's avatar
stevenn committed
678
679
680
    return(Contrast)
    
  })
681
682
  
  
stevenn's avatar
stevenn committed
683
684
685
686
687
  output$ContrastOverview <- renderPrint({
    
    resDiff = ResDiffAnal()
    dds = resDiff$dds
    names = resultsNames(dds)
stevenn's avatar
stevenn committed
688
689
    
    cont = input$ContrastList
stevenn's avatar
stevenn committed
690
    filesize = file.info(namesfile)[,"size"]
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
691
    if(is.na(filesize)){filesize=0}
stevenn's avatar
stevenn committed
692
693
694
695
696
697
    if(filesize!=0)
    { 
      ContrastBase = read.table(namesfile,header=TRUE)
      ind = which(colnames(ContrastBase)%in%cont)
      div(HTML(PrintContrasts(names,sapply(ContrastBase[,ind],as.numeric),cont)))
    }
stevenn's avatar
stevenn committed
698
  })
699
700
  
  
stevenn's avatar
stevenn committed
701
702
703
704
705
706
  ## Add contrast function
  AddCont <-eventReactive(input$AddContrast,{
    
    resDiff = ResDiffAnal()
    dds = resDiff$dds
    names = resultsNames(dds)
707
    
stevenn's avatar
stevenn committed
708
    BaseContrast(input,names,namesfile)
Stevenn Volant's avatar
Stevenn Volant committed
709
710
711
    filesize = file.info(namesfile)[,"size"]
    if(is.na(filesize)){filesize=0}
    if(filesize!=0) tmp = read.table(namesfile,header=TRUE)
stevenn's avatar
stevenn committed
712
713
    Contrast = colnames(as.matrix(tmp))
    updateSelectInput(session, "ContrastList","Contrasts",Contrast)
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
714
    updateSelectInput(session, "ContrastList_table","Contrasts",Contrast)
715
    updateSelectInput(session, "ContrastList_table_Visu","For which contrasts",Contrast)
716
    updateSelectInput(session, "ContrastList_table_VisuComp","For which contrasts",Contrast)
717
    updateSelectInput(session, "ContrastList_table_FC","Contrasts (Min = 2)",Contrast)
stevenn's avatar
stevenn committed
718
  })
719
  
stevenn's avatar
stevenn committed
720
721
  ## Add contrast 
  observeEvent(input$AddContrast,{  
stevenn's avatar
stevenn committed
722
    
stevenn's avatar
stevenn committed
723
    AddCont()
stevenn's avatar
stevenn committed
724
    
Stevenn Volant's avatar
Stevenn Volant committed
725
  },priority=1)
726
727
  
  
728
729
730
731
732
  ## Add contrast function
  AddContEasy <-eventReactive(input$AddContrastEasy,{
    
    resDiff = ResDiffAnal()
    dds = resDiff$dds
733
    target = resDiff$target
734
    names = resultsNames(dds)
735
736
737
738
739
740
741
    
    BaseContrastEasy(input,names,namesfile,target)
    filesize = file.info(namesfile)[,"size"]
    if(is.na(filesize)){filesize=0}
    if(filesize!=0) tmp = read.table(namesfile,header=TRUE)
    Contrast = colnames(as.matrix(tmp))
    
742
743
    updateSelectInput(session, "ContrastList","Contrasts",Contrast)
    updateSelectInput(session, "ContrastList_table","Contrasts",Contrast)
744
    updateSelectInput(session, "ContrastList_table_Visu","For which contrasts",Contrast)
745
    updateSelectInput(session, "ContrastList_table_VisuComp","For which contrasts",Contrast)
746
    updateSelectInput(session, "ContrastList_table_FC","Contrasts (Min = 2)",Contrast)
747
  })
stevenn's avatar
stevenn committed
748
  
749
750
751
752
753
  ## Add contrast 
  observeEvent(input$AddContrastEasy,{  
    
    AddContEasy()
    
svolant's avatar
svolant committed
754
  },priority=1)
755
756
  
  
757
758
759
760
761
  AddContFromFile <-eventReactive(input$fileContrast,{ 
    
    res = ReadContrastFile()
    createdCont = NULL
    filesize = file.info(namesfile)[,"size"]
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
762
    if(is.na(filesize)){filesize=0}
763
    if(filesize!=0){ createdCont = read.table(namesfile,header=TRUE) }
764
    
765
766
767
768
769
    if(!is.null(res))
    { 
      if(!is.null(createdCont)) res = cbind(res,createdCont)
      updateSelectInput(session, "ContrastList","Contrasts",colnames(res))
      updateSelectInput(session, "ContrastList_table","Contrasts",colnames(res))
770
      updateSelectInput(session, "ContrastList_table_Visu","For which contrasts",colnames(res))
771
      updateSelectInput(session, "ContrastList_table_VisuComp","For which contrasts",colnames(res))
772
      updateSelectInput(session, "ContrastList_table_FC","Contrasts (Min = 2)",colnames(res))
773
774
775
      write.table(res,namesfile,row.names=FALSE)
    }
  })
776
777
  
  observeEvent(input$fileContrast,{ 
778
    
779
    AddContFromFile()
Stevenn Volant's avatar
Stevenn Volant committed
780
  },priority=1)
781
782
  
  
stevenn's avatar
stevenn committed
783
784
785
786
787
  ## Remove contrast function
  RemoveCont <-eventReactive(input$RemoveContrast,{
    
    ## get the size of the contrast base file
    filesize = file.info(namesfile)[,"size"]
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
788
    if(is.na(filesize)){filesize=0}
stevenn's avatar
stevenn committed
789
790
791
792
793
794
    if(filesize!=0)
    { 
      tmp = read.table(namesfile,header=TRUE)
      ind = which(colnames(tmp)%in%input$ContrastList)
      matKept = as.matrix(tmp[,-ind])
      ContrastKept = colnames(tmp)[-ind]
stevenn's avatar
stevenn committed
795
      
stevenn's avatar
stevenn committed
796
797
798
      if(ncol(matKept)>0) write.table(matKept,namesfile,row.names=FALSE,col.names = ContrastKept)
      else file.create(namesfile,showWarnings=FALSE)
      updateSelectInput(session, "ContrastList","Contrasts",ContrastKept)
Amine  GHOZLANE's avatar
Amine GHOZLANE committed
799
      updateSelectInput(session, "ContrastList_table","Contrasts",ContrastKept)
800
      updateSelectInput(session, "ContrastList_table_Visu","For which contrasts",ContrastKept)
801
      updateSelectInput(session, "ContrastList_table_VisuComp","For which contrasts",ContrastKept)
802
      updateSelectInput(session, "ContrastList_table_FC","Contrasts (Min = 2)",ContrastKept)
stevenn's avatar
stevenn committed
803
    }
stevenn's avatar
stevenn committed
804
805
806
807
808
809
810
811
812
  })
  
  
  
  ## Remove contrast
  observeEvent(input$RemoveContrast,{  
    
    RemoveCont()
    
Stevenn Volant's avatar
Stevenn Volant committed
813
  },priority=1)
814
  
Stevenn Volant's avatar
Stevenn Volant committed
815
816
817
  ## Remove all contrasts
  RemoveAllCont <-eventReactive(input$RunDESeq,{
    
818
819
820
821
822
823
    file.create(namesfile,showWarnings=FALSE)
    updateSelectInput(session, "ContrastList","Contrasts",NULL)
    updateSelectInput(session, "ContrastList_table","Contrasts",NULL)
    updateSelectInput(session, "ContrastList_table_Visu","For which contrasts",NULL)
    updateSelectInput(session, "ContrastList_table_VisuComp","For which contrasts",NULL)
    updateSelectInput(session, "ContrastList_table_FC","Contrasts (Min = 2)",NULL)
Stevenn Volant's avatar
Stevenn Volant committed
824
  })
825
  
Stevenn Volant's avatar
Stevenn Volant committed
826
827
  ## Remove all contrast
  observeEvent(input$RunDESeq,{  
stevenn's avatar
stevenn committed
828
    
Stevenn Volant's avatar
Stevenn Volant committed
829
    RemoveAllCont()
stevenn's avatar
stevenn committed
830
    
Stevenn Volant's avatar
Stevenn Volant committed
831
  })
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
  
  # Infobox Contrast
  output$InfoContrast <- renderInfoBox({
    input$RunDESeq
    input$AddContrast
    input$AddContrastEasy
    input$RemoveContrast
    input$fileContrast
    resDiff = ResDiffAnal()
    res=NULL
    if(!is.null(resDiff)){
      
      res = infoBox("Contrasts", subtitle = h6("At least one contrast (non null) must be defined"), icon = icon("warning"),color = "light-blue",width=NULL,fill=TRUE)
      test = FALSE
      filesize = isolate(file.info(namesfile)[,"size"])
      
      if(is.na(filesize)){filesize=0}
      if(filesize!=0) 
      {
        tmp = read.table(namesfile,header=TRUE)
        if(any(as.vector(tmp)!=0)) test = TRUE
      }
      
      if(test) res = infoBox("Contrasts", subtitle = h6("Contrasts OK"), icon = icon("thumbs-o-up"),color = "green",width=NULL,fill=TRUE)
svolant's avatar
svolant committed
856
    }
857
858
    return(res)
  })
859
860
  
  
861
862
863
864
865
866
867
868
  
  output$contrastBox <- renderUI({
    
    resDiff = ResDiffAnal()
    int = input$Interaction2
    
    if(!is.null(resDiff))
    { 
869
870
871
872
873
874
875
876
877
878
879
      ## Check the R version
      if(as.numeric(R.Version()$major)<=3 && as.numeric(R.Version()$minor) <=1.2){
        box(title="Contrasts (New)",width = NULL, status = "primary", solidHeader = TRUE,collapsible = TRUE,collapsed = FALSE,
            fluidRow(
              column(width=3,selectInput("Select1_contrast","Compare","")),
              column(width=3,selectInput("Select2_contrast","To","")),
              if(length(int)>=1) column(width=3,selectInput("Select3_contrast",label=h6(strong("For")),"")),
              column(width=3,br(),actionButton("AddContrastEasy","Add",icon = icon("plus")))
            )
        )
      }
880
881
    }
    
882
883
    
    
884
  })
885
886
  
  ModifMod_ContEasy <-eventReactive(input$Select1_contrast,{
svolant's avatar
svolant committed
887
    input$RunDESeq
888
889
890
891
892
893
    resDiff = ResDiffAnal()
    int = input$Interaction2
    target = as.data.frame(resDiff$target)
    
    InterVar = input$InterestVar
    
svolant's avatar
svolant committed
894
    
svolant's avatar
svolant committed
895
    
896
    ## Get the selected variable from the selected modality
svolant's avatar
svolant committed
897
    Sel_Var = InterVar[which(unlist(lapply(as.data.frame(target[,InterVar]),FUN = function(x){input$Select1_contrast%in%x})))]
898
    
svolant's avatar
svolant committed
899
    ModInterestCond = levels(sapply(target[,Sel_Var],as.factor))
900
901
902
903
904
    ModInterestCond = ModInterestCond[-which(ModInterestCond==input$Select1_contrast)]
    
    updateSelectInput(session,"Select2_contrast","To",ModInterestCond)
  })
  
905
  
906
907
908
909
910
911
912
913
914
915
916
917
918
  observeEvent(input$Select1_contrast,{ 
    
    ModifMod_ContEasy()
  })
  
  
  ModifMod_ContEasyFrom <-eventReactive(input$RunDESeq,{
    
    resDiff = ResDiffAnal()
    int = input$Interaction2
    target = as.data.frame(resDiff$target)
    
    InterVar = input$InterestVar
svolant's avatar
svolant committed
919
    
920
    ## Remove numeric variable
svolant's avatar
svolant committed
921
    ind = unlist(lapply(as.data.frame(target[,InterVar]),is.numeric))
922
    InterVar = InterVar[!ind]
svolant's avatar
svolant committed
923
924
    target_int = lapply(as.data.frame(target[,InterVar]),as.factor)
    ModInterestAll = unique(unlist(lapply(target_int,levels)))
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
    
    updateSelectInput(session, "Select1_contrast",label="Compare",ModInterestAll)
  })
  
  
  observeEvent(input$RunDESeq,{ 
    
    ModifMod_ContEasyFrom()
  })
  
  
  
  ModifMod_ContEasyFor <-eventReactive(input$Select1_contrast,
    {
    
    resDiff = ResDiffAnal()
    int = input$Interaction2
    ModInterestFor = "All"
    target = as.data.frame(resDiff$target)
    
    InterVar = input$InterestVar
    
    ## Get the selected variable from the selected modality
svolant's avatar
svolant committed
948
    Sel_Var = InterVar[which(unlist(lapply(as.data.frame(target[,InterVar]),FUN = function(x){input$Select1_contrast%in%x})))]
949
950
951
952
953
954
955
956
957
958
   
    
    ## Keep only the variables in interactoin with Sel_Var
    if(!is.null(Sel_Var) && length(int)>0 && length(Sel_Var)>0){
      indInter = grep(Sel_Var,int)
      if(length(indInter)>0) int = int[indInter]
      var_Inter = unique(unlist(strsplit(int,":"))) 
      var_Inter = var_Inter[-which(var_Inter%in%Sel_Var)]
      
      ## remove if numeric
svolant's avatar
svolant committed
959
      if(length(var_Inter)>1){ind = unlist(lapply(as.data.frame(target[,var_Inter]),is.numeric));var_Inter = var_Inter[!ind]}
960
961
      if(length(var_Inter)==1){ind = is.numeric(