过滤数据使用textinput in shiny got error:参数不是字符向量

时间:2017-07-21 09:10:17

标签: r filter shiny

在enc2utf8中出现错误:参数不是字符向量。      我使用selectInput,checkboxGroupInput,textInput来过滤服务器中的数据,并得到上述错误;我已经尝试过filter(),subset(),这些()但是当过滤数据超过四列并且参数是字符向量时,它们会转向同样的问题(例如,%c中的公司%('本田','日产'))

在数据集中,有市场公司 Med_type Med_id 衡量< / strong>,日期列。

在代码中,品牌 name_tmp 是用于过滤数据的字符向量。

library(shiny)
library(dplyr)
library(DT)

ui<-fluidPage(pageWithSidebar(
  headerPanel('Table'),
  sidebarPanel(
    fileInput('file1', 'Upload Data',
              accept=c('text/csv', 'text/comma-separated-values,text/plain')),
    selectInput('TA',"Market-type",c('Asia','Europe')),
    selectInput('Length',"Length",c('1 year'='0','2 years'='1','3 years'='2','4 years'='3','5 years'='4')),        
    selectInput('NoBrand',"Top Brand/Cor",c('one'='1','two'='2','three'='3','four'='4','five'='5')),
    selectInput('Period',"Period",c('Quarter'='Quarter','YR'='year')),
    checkboxGroupInput('Measure','Measurement',c('Unit','RMB','Dollar')),
    selectInput('Med_type','Med_type',c('Imported','Joint Venture','Local')),
    textInput('Med_id','Med_id',value='Honda;Nissan')),
           
    
  mainPanel(
    dataTableOutput('table')
  )))
  
  
  
  
  server<-function(input,output){
  options(shiny.maxRequestSize=100*1024^2)

  ## importing dataset
  tmp <- reactive({inFile <- input$file1
  if (is.null(inFile))
    return(NULL)
  data<-read_csv(inFile$datapath,na=c("", "NA",'-'))
  
  })
  

  
  
 
 tmp2<-reactive({
   ## modify the inputs
   
   data_df <- tbl_df(tmp())
   year<-(2017-as.numeric(input$Length)):2017
   name_tmp<-as.vector(unlist(strsplit(input$Med_id,';')))
   temp_data<-summarize(group_by(data_df,Corp),VValue=sum(value,na.rm = TRUE))
   brands<-as.vector(arrange(temp_data,desc(VValue))$Corp[1:as.numeric(input$NoBrand)])
   
   ## filtering by the input
   mod_data<-data_df %>% 
     select(Market,Corp,Med_type,Med_id,measure,date,value) %>%
     filter(Market==input$TA,
            Corp%in%brands,
            Med_id%in%name_tmp,
            Med_type==input$Med_type,
            measure==input$Measure,
            substr(date,1,4)%in%year
     )
 
   
   
   
   ## Aggregation() & reformating
   if(input$Period=="year"){
     mod_data$date<-substr(mod_data$date,1,4)
     mod_data<-group_by_if(mod_data,is.character)
     mod_data<-summarise(mod_data,Value=sum(value,na.rm = TRUE))
     
   } else {mod_data<-summarise(group_by_if(mod_data,is.character),Value=sum(value,na.rm=TRUE))}
        
  
   
   
 })
  
  
  ## printing table
  
  output$table<-DT::renderDataTable({tmp2()})
  
  
 
      }
shinyApp(ui=ui,server = server)

2 个答案:

答案 0 :(得分:1)

问题已经解决了。 错误实际上来自spread()函数。如果数据框为空,spread()将调用Error in enc2utf8: argument is not a character vector。所以我添加了一些条件参数,以防止数据帧在运行shinyapp后变空。此外,isolate()也是用户控制输入执行的有用功能。

答案 1 :(得分:0)

在对所有数据进行子集之前尝试print(input$measure),将其初始化为NULL。你应该添加:

if(is.null(input$measure))
  measure = unique(data_df$measure)
else
  measure = input$Measure

并修改

measure==input$Measure,

measure==measure

因此,当使用没有选择时,该列上实际上没有过滤器。

工作示例

以下对我来说很好。请注意,我已经创建了自己的数据集&#39; df&#39;并修改了你的tmp()反应,所以在这个例子中它使用我的df作为输入数据集。

df = data.frame(Market=c("Asia","Asia","Europe","Europe"),
                Corp=c("a","b","c","d"),
                Med_type = c('Imported','Joint Venture','Local','Local'),
                Med_id = c("Honda","Honda","Nissan","Nissan"),
                measure=c('Unit','RMB','Dollar','Dollar'),
                date = c('2017','2016','2017','2016'),
                value=c(1,2,3,4 ))


library(shiny)
library(dplyr)
library(DT)

ui<-fluidPage(pageWithSidebar(
  headerPanel('Table'),
  sidebarPanel(
    fileInput('file1', 'Upload Data',
              accept=c('text/csv', 'text/comma-separated-values,text/plain')),
    selectInput('TA',"Market-type",c('Asia','Europe')),
    selectInput('Length',"Length",c('1 year'='0','2 years'='1','3 years'='2','4 years'='3','5 years'='4')),        
    selectInput('NoBrand',"Top Brand/Cor",c('one'='1','two'='2','three'='3','four'='4','five'='5')),
    selectInput('Period',"Period",c('Quarter'='Quarter','YR'='year')),
    checkboxGroupInput('Measure','Measurement',c('Unit','RMB','Dollar')),
    selectInput('Med_type','Med_type',c('Imported','Joint Venture','Local')),
    textInput('Med_id','Med_id',value='Honda;Nissan')),


  mainPanel(
    dataTableOutput('table')
  )))




server<-function(input,output){
  options(shiny.maxRequestSize=100*1024^2)

  ## importing dataset
  tmp <- reactive({ 

  df

  })





  tmp2<-reactive({
    ## modify the inputs

    data_df <- tbl_df(tmp())
    year<-(2017-as.numeric(input$Length)):2017

    name_tmp<-as.vector(unlist(strsplit(input$Med_id,';')))

    temp_data<<-summarize(group_by(data_df,Corp),VValue=sum(value,na.rm = TRUE))

    brands<-as.vector(arrange(temp_data,desc(VValue))$Corp[1:as.numeric(input$NoBrand)])

    if(is.null(input$measure))
      measure = unique(data_df$measure)
    else
      measure = input$Measure

    ## filtering by the input
    mod_data<-data_df %>% 
      select(Market,Corp,Med_type,Med_id,measure,date,value) %>%
      filter(Market==input$TA,
             Corp%in%brands,
             Med_id%in%name_tmp,
             Med_type==input$Med_type,
             measure==measure,
            substr(date,1,4) %in% year
      )


    print(mod_data)

    ## Aggregation() & reformating
    if(input$Period=="year"){
      mod_data$date<-substr(mod_data$date,1,4)
      mod_data<-group_by_if(mod_data,is.character)
      mod_data<-summarise(mod_data,Value=sum(value,na.rm = TRUE))

    } else {mod_data<-summarise(group_by_if(mod_data,is.character),Value=sum(value,na.rm=TRUE))}




  })


  ## printing table

  output$table<-DT::renderDataTable({tmp2()})



}
shinyApp(ui=ui,server = server)