0

my code has been working with data.frames, but now that I converted to data.table I have trouble with filtering the data.table by the user's input. filter_expr is set TRUE and at the end only rows that are TRUE are supposed to be in the final table version. I think the %in% operatormight be the problem, but I could not find an answer yet.

dput of my date:

structure(list(fruit = c("Apple", "Apple", "Apple", "Apple", 
"Apple", "Apple", "Banana", "Banana", "Banana", "Banana", "Banana", 
"Banana", "Citrus", "Citrus", "Citrus", "Citrus", "Citrus", "Citrus"
), Month = c(1L, 9L, 12L, 1L, 9L, 12L, 1L, 9L, 12L, 1L, 9L, 12L, 
1L, 9L, 12L, 1L, 9L, 12L), Fertilizer = c("A", "A", "A", "B", 
"B", "B", "A", "A", "A", "B", "B", "B", "A", "A", "A", "B", "B", 
"B"), red = c("+", "+", "+", "+", "+", "+", "+", "+", "+", "+", 
"+", "+", "+", "+", "+", "+", "+", "+"), green = c("+", "-", 
"+", "-", "+", "-", "+", "-", "+", "-", "+", "-", "+", "-", "+", 
"-", "+", "-"), yellow = c("+", "+", "-", "+", "+", "-", "+", 
"+", "-", "+", "+", "-", "+", "+", "-", "+", "+", "-")), .Names = c("fruit", 
"Month", "Fertilizer", "red", "green", "yellow"), row.names = c(NA, 
-18L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x10280e978>)

I used this file for testing.

library(shiny)
library(data.table)
library(DT)

ui <- (fluidPage(tagList(
  navbarPage(
    "My Application",
    tabPanel("Pregated Data",
             sidebarLayout(
               sidebarPanel(
                 conditionalPanel(condition = "input.tabselected == 1",
                                  fileInput(inputId = 'file_input', 'Choose CSV File',
                                            accept=c('text/csv',
                                                     'text/comma-separated-values,text/plain', 
                                                     '.csv')),
                                  #progressbar
                                  tags$hr(),
                                  checkboxInput('header', 'Header', TRUE),
                                  radioButtons('sep', 'Separator',
                                               c(Comma=',',
                                                 Semicolon=';',
                                                 Tab='\t'),
                                               ',')

                 ),
                 conditionalPanel(condition = "input.tabselected == 2",
                                  uiOutput("file_input"))
               ),
               mainPanel(
                 tabsetPanel(
                   tabPanel("Data", value = 1, dataTableOutput('table1')),
                   tabPanel("checkboxes",value = 2,conditionalPanel(condition = "input.choice ==1"), 
                            dataTableOutput('fruit_table')), 
                            id = "tabselected"
                 )
               )
             )
    )
  )
)))



server <- function(input, output) {

  fileData <- reactive(
    if (is.null(input$file_input)){
      return()
    }else{
      tdata <- fread(input$file_input$datapath, header=input$header, sep=input$sep)
      return(tdata)
    }
  )

  output$table1 <- renderDataTable({
    if(is.null(fileData())){
      return(NULL)
    }else{
      datatable( fileData(), options = list(pageLength = 25))
    }
  })


  output$file_input <- renderUI ({
    if(is.null(fileData())){
      return()
    }else{
      tagList(
        checkboxGroupInput(inputId = "fruit",
                           label = "fruit",
                           choices = c(unique(fileData()[,get("fruit")])),
                           selected = fileData()[1, 1, with = FALSE]),
        radioButtons(inputId = "month",
                     label = "Month",
                     choices =unique(fileData()[,get("Month")]),
                     selected = fileData()[1,Month],
                     inline = TRUE),
        checkboxGroupInput(inputId = "tube",
                           label = "Fertilizer",
                           choices = unique(fileData()[,get("Fertilizer")]),
                           selected = fileData()[1, 3, with = F]),
        ###checkboxes from Loop:
        lapply(1:(length(fileData())-3), function(i) {
          checkboxGroupInput(inputId = paste0("color",i),
                             label = colnames(fileData()[,i+3, with = FALSE]),
                             choices = c(unique(fileData()[,get(colnames(fileData()[,i+3, with = FALSE]))])),
                             inline = TRUE,
                             selected = fileData()[1, i+3, with = FALSE])
        }
      )
      )
    }})   

  ###returns table form boolean-Gates csv file rigth after upload
  output$fruit_table <- renderDataTable({
    if(is.null(fileData())){
      return(NULL)
    }else{

      validate(
        need(input$fruit, 'Check at least one fruit!'),
        need(input$tube, 'Check at least one Fertilizer!'),
        need(!is.null(input$color1) | !is.null(input$color2) | !is.null(input$color3), 
             "Check at least one Color!")
      )

      filter_expr <- TRUE

      if (!(is.null(input$fruit))) {
        filter_expr <- filter_expr & fileData()[,fruit] %in% input$fruit
      }
      # 

      if (!(is.null(input$month))) {
        filter_expr <- filter_expr & fileData()[,Month]  == as.integer(input$month)
      }

      if (!(is.null(input$tube))) {
        filter_expr <- filter_expr & fileData()[,Fertilizer] %in% input$tube
      }


      #colname <- c(colnames(fileData()[,4:length(fileData())]))
      #print(colname)
      lapply(1:(length(fileData())-3), function(i) {
        if (!(is.null(paste0("input$color",i)))) {
          filter_expr <- filter_expr & fileData()[,colnames(fileData()[,3+i,with = FALSE])] %in% paste0("input$color",i)
          print(fileData()[,colnames(fileData()[,3+1,with = FALSE])]%in% paste0("input$color",i))
          #print(fileData()[,colname[i],with = FALSE])
        }

      })

      datatable(fileData()[filter_expr,],options = list(pageLength = 25))

    }
  })
}
shinyApp(ui = ui, server = server)

Thanks for any help!

Rivka
  • 307
  • 1
  • 5
  • 19

1 Answers1

2

Assuming this would apply to your example, here a toy example. The difference is naming the variable vs inserting the col id.

iris[,5] %in% "setosa" # outputs a vector
iris2 = iris
setDT(iris2)

iris2[,5] %in% "setosa" # outputs single T/F
iris2[,Species] %in% "setosa" # outputs a vector

Not sure if this is what you need..

timfaber
  • 2,060
  • 1
  • 15
  • 17
  • it is! thanks for pointing out the difference of iris[,5] and iris[,Species] in data.table. again. – Rivka Jun 08 '17 at 12:50
  • 1
    :) Confuses me a lot still, that's why I always keep this one close by https://s3.amazonaws.com/assets.datacamp.com/img/blog/data+table+cheat+sheet.pdf – timfaber Jun 08 '17 at 13:00
  • Any Idea why the loop forr the colors is not working? – Rivka Jun 08 '17 at 14:19
  • 1
    Ah yes, another data.table thing. I found this solution: First assign the names to a vector and input the vector as columns like `colname=c("V1","V2")` and `DT[,colname,with=FALSE]` (based on the cheatsheet example). See https://stackoverflow.com/questions/12391950/select-assign-to-data-table-variables-which-names-are-stored-in-a-character-ve – timfaber Jun 08 '17 at 14:53
  • sorry, but I cannot just substitute `filter_expr <- filter_expr & fileData()[,colnames(fileData() [,i+3, with = FALSE])] %in% paste0("input$color",i)` with `filter_expr <- filter_expr & fileData()[,colname,with = FALSE] %in% paste0("input$color",i)`what am I missing here? – Rivka Jun 08 '17 at 18:12
  • What did you write as colname? And what is your desired output of that line? Do you want it to produce a T/F? Also, can you dput the data than I can check the entire app. – timfaber Jun 09 '17 at 07:28
  • I want it to produce true or false. colname now is a vector of the column names of columns 4:6. – Rivka Jun 09 '17 at 07:54
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146236/discussion-between-timfaber-and-rivka). – timfaber Jun 09 '17 at 08:58