2016-10-28 8 views
1

動的ユーザ入力ごとにデータをフィルタリングするのが好きです。下記のサンプルコードは実行可能ですが、現在、データをフィルタリングするロジックはありません。したがって、表は変数の選択に関係なく変更されません。
コードには主に3つのコンポーネントがあります。1.コードの最初の数行は、その場でコントロールウィジェットを作成する際に情報を使用できるデータフレームを作成します。 2. uiコード; 3. serverは現在、コントロールウィジェットをその場で作成するロジックを持っており、動的に作成されたコントロールウィジェットとフィルタデータ(さまざまな目的で使用される)から情報を使用する方法を理解する必要があります。変数の数とそのフィルタリングの範囲をどのように追跡するのか分かりません。大いに感謝する提案。
動的ユーザ入力ごとのデータのサブセット化またはフィルタリング

## Create a data frame of which information is used in creating (dynamical) control widgets 
varnames <- names(iris[,1:4]) # names 
varinit <- apply(iris[,1:4],2,median) # initival value used in slider 
varmin <- apply(iris[,1:4],2,min) # min. 
varmax <- apply(iris[,1:4],2,max) # max. 

## dataframe 
vardf <- data.frame(varnames,varmin,varmax,varinit) 

ui <- fluidPage(
    checkboxGroupInput("ConditioningVariables", "Conditioning variables (choose one or more):", 
         varnames,inline = TRUE), 
uiOutput("ControlWidgetsofConditioningVariables"), 
    tableOutput("data") 
) 

server <- function(input, output, session) { 

    output$ControlWidgetsofConditioningVariables <- renderUI({ 
     if (is.null(input$ConditioningVariables)){ 
     return() 
     } else { 
     selvarnames = sort(input$ConditioningVariables) 
     selpos = sapply(selvarnames,function(x) which(varnames==x)) 
     # create a taglist of dynamic widgets 
     ListofDynamicWidgets <- lapply(selpos, function(x){sliderInput(as.character(vardf[x,1]), 
                  as.character(vardf[x,1]), 
                  vardf[x,2],vardf[x,3], 
                  vardf[x,4],.1)}) 
     do.call(tagList, ListofDynamicWidgets) 
     } 
    }) 
    ## filter data as per selected variables and their range 
    ## this is where I'm kind of struck, I think I need to track number of variables (is list good idea?) 
    ## and filter as per selected range of a specific variable 
    newdata <- reactive({ 
     subset(iris) 
    }) 
    output$data <- renderTable({ newdata() }) 
    } 
shinyApp(ui, server) 

答えて

1

ここに1つのアプローチは、(私は少しのウィジェットを生成するためのコードを変更していることに注意してください)です。主な考え方は、範囲ベクトル(conds)の名​​前付きリストを生成し、その範囲をフィルタリング条件(subs)を表す文字列のリストに変換し、それらを1つの長い文字列に分解し、サブセットとして使用しますfilter_()の引数

library(dplyr) 
server <- function(input, output, session) { 
    allControls <- lapply(setNames(varnames, varnames), function(x) { 
    sliderInput(x, x, varmin[x], varmax[x], c(varmin[x], varinit[x]), 
     round = -2) 
    }) 
    output$ControlWidgetsofConditioningVariables <- renderUI({  
    if (is.null(input$ConditioningVariables)){ 
     return() 
    } else { 
     allControls[input$ConditioningVariables] 
    } 
    }) 
    ## filter data as per selected variables and their range 
    newdata <- reactive({ 
    if(!is.null(input$ConditioningVariables)) { 
     cond_names <- input$ConditioningVariables 
     conds <- lapply(setNames(cond_names, cond_names), function(x) input[[x]]) 
     subs <- mapply(function(name, range){ 
     if (!is.null(range)) 
      sprintf("%1$s >= %2$f & %1$s <= %3$f", name, range[1], range[2]) 
     }, names(conds), conds) 
     subs <- subs[!sapply(subs, is.null)] 
     if (length(subs) > 0) 
     filter_(iris, paste0(subs, collapse = " & "))  
     } else { 
     iris 
     } 
    }) 
    output$data <- renderTable({ newdata() }) 
} 

出力:グッド

enter image description here

+0

ウィジェットを生成するために、 'tagList'を使用するために必須ではないことを知っています。データのフィルタリング - シンプルに見えるコマンドの非常に巧妙な使用。驚くばかり。 – SatishR

+0

基準を満たす行位置(または数値)を直接与えるコマンドはありますか?通常は、すべての行番号を別々の列に保存し、その特定の列から行番号を抽出します。 – SatishR

+1

これについて新しい質問を開いたり、既存の質問があるかどうかを確認することができます。しかし、ここでは1つのアプローチの例があります: 'with(iris、which(eval(parse(text =" Sepal.Length> = 5&Sepal.Length <= 6 ")))))' –

関連する問題