2017-08-29 2 views
0

私はシャイニーを学び、シンプルなアプリケーションを開発中です。プログラムの開始により、ユーザーはCSVファイルをインポートし、必要に応じてフィルタ変数を適用することができます。この段階では、フィルタ変数としてのみ因子を使用できます。フィルタを反復的に適用します。したがって、因子レベルに基づいてフィルタを適用し、その後、他の因子レベルを適用することができます。シャイニーで反応性のオブジェクトをサブセット化

リアクティブデータフレームのサブセットを作成できる最も良いアプリケーションは、データフレームをリアクティブ値として適用することでした。これはうまくいくようですが、解決する方法を見つけられないという2つの問題があります。

1)フィルタ処理が反復処理である場合、フィルタリング処理中に適用される各変数とレベルを追跡して出力したいと思います。私が把握できる最良の方法は、グローバル変数(< < - )を作成し、renderTextを使用してフィルタの適用ボタンを押した後に内容を出力することでした。問題は、renderTextが画面上で点滅してすぐに消えることです。私は、テキストが正しく保存されていることを確認するprintステートメントをコンソールステートメントに含めました。私は、これが反応的なデータフレームと更新プロセスに適用されているフィルタから起こっていると信じていますが、テキストが画面上で消えないようにする方法を理解できませんか?

2)光沢のあるコードの最後に反応性データフレームを保存しようとすると、次のエラーが発生します。 "警告:$:$演算子でエラーが発生しました。私はいくつかのことを試しましたが、オブジェクト "file $ dfSource"が通常の反作用データフレームdfSource()のようではないので、ここで何が起こっているのかを実際に理解していませんか?

以下の光沢のあるアプリは、虹彩データを使用するので、使いやすく、テストしやすいです。私は、データフレームを反作用値に適用することがこれをプログラムする最良の方法であるかどうか、またはこれをすべて行う簡単な方法があるかどうかはわかりません。

library(shiny) 
allfilters <- c() 

ui <- (fluidPage(

# Application title 
titlePanel("Filter Data"), 

# Input Forms 
sidebarLayout(
sidebarPanel(
    h3("Data"), 
     checkboxInput("selectFilter", label = "Apply Filter Variable", value = FALSE), 
     uiOutput("selectFilterVar"), 
    uiOutput("selectFilterGroup"), 
    helpText("Apply filter to data"), 
    uiOutput("selectFilterButton"), 
    helpText("Reset data to total"), 
    uiOutput("selectResetButton"), 
    h3("Download Data"),  
     helpText("Download Data"), 
     downloadButton("downloadData", "Download File") 
    ), 

# Output Forms 
mainPanel(
    tabsetPanel(
    tabPanel("Summary", 
    h2("Output Summary"), 
    textOutput("ncases"), 
    textOutput("selectedfilters"))) 
) 
) 
)) 

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

data <- iris 
file <- reactiveValues(dfSource = data) 

## Select Filter Variable 
output$selectFilterVar <- renderUI({ 
     req(file$dfSource) 
     if (input$selectFilter){ 
     selectInput("filterVar", "Select Filter Variable", multiple = FALSE, choices = sort(names(file$dfSource[, sapply(file$dfSource, is.factor), drop = FALSE]))) 
}   
})   

# Select Filter Group(s) 
output$selectFilterGroup <- renderUI({ 
     req(file$dfSource) 
     req(input$filterVar) 
     if (input$selectFilter){ 
     selectInput("filterGroup", "Select Filter Group", multiple = TRUE, choices = sort(unique(file$dfSource[,input$filterVar]))) 
} 
}) 

# Apply Filter Button 
output$selectFilterButton <- renderUI({ 
     req(file$dfSource) 
     if (input$selectFilter) { 
      actionButton("filterButton", "Apply Filter") 
} 
}) 

# Apply filter group to data 
    observeEvent(input$filterButton, { 
    temp <- file$dfSource[(file$dfSource[,input$filterVar] %in% c(input$filterGroup)),] 
    file$dfSource <- temp 
}) 

# Reset Total Sample Button 
output$selectResetButton <- renderUI({ 
     req(file$dfSource) 
     if (input$selectFilter) { 
      actionButton("resetButton", "Reset Total") 
} 
}) 

# Reset data to total sample 
    observeEvent(input$resetButton, { 
    file$dfSource <- data 
    updateCheckboxInput(session, "selectFilter", value = FALSE) 
    allfilters <- NULL 
}) 

## Summary number of cases 
output$ncases <- renderText({ 
    req(file$dfSource) 
    mainTitle <- paste("Number of cases =" , nrow(file$dfSource)) 
    return(mainTitle) 
}) 

## Capture selected filter variables in global object 
testfilter <- eventReactive(input$filterButton, { 
    appliedfilter <- paste0(input$filterVar, "(", input$filterGroup,")") 
     if (is.null(allfilters)) { 
     allfilters <<- paste("Selected Filters:", appliedfilter) 
     } else { 
     allfilters <<- paste(allfilters, "&", appliedfilter) 
    } 
    return(allfilters) 
    }) 

# Print out filter variables in global object 
output$selectedfilters <- renderText({ 
    filteroutput <- testfilter() 
    print(filteroutput) 
    return(filteroutput) 
}) 

## Save out case data file 
output$downloadData <- downloadHandler(
    filename = function() { 
     paste("data-", Sys.Date(), ".csv", sep="") 
    }, 
    content = function(file) { 
    write.csv(file$dfSource, file) 
    } 
) 

}) 

shinyApp(ui, server) 

答えて

0

1)グローバル変数を格納することは、おそらく良い考えではありません(光沢のあるスコープはすでに複雑になっています)。あなたはすでにreactiveValuesオブジェクトを持っていますが、それを使わないのはなぜですか?

しかし、これだけでは不十分です。問題はeventReactiveのようです - 私はなぜそれほど確かではありません。

これは動作します:

# this replaces the testfilter eventReactive 
observeEvent(input$filterButton, { 
    appliedfilter <- paste0(input$filterVar, "(", input$filterGroup,")") 
    if (is.null(file$allfilters)) { 
    file$allfilters <- paste("Selected Filters:", appliedfilter) 
    } else { 
    file$allfilters <- paste(file$allfilters, "&", appliedfilter) 
    } 
}) 

# Print out filter variables in global object 
output$selectedfilters <- renderText({ 
    filteroutput <- file$allfilters 
    print(filteroutput) 
    return(filteroutput) 
}) 

2)エラーはあなたがdownloadHandlerに渡すコンテンツ機能です。このパラメータはfileと呼ばれ、filereactiveValuesを示しています。これは動作します:

## Save out case data file 
    output$downloadData <- downloadHandler(
    filename = function() { 
     paste("data-", Sys.Date(), ".csv", sep="") 
    }, 
    content = function(filetarget) { 
     write.csv(file$dfSource, filetarget) 
    } 
) 

PS広告1:それは代わりに、フィルタリングされたデータフレームとフィルタをリストする文字列を格納する、フィルタを保存した方がよいかもしれません。ユーザーが気を変えた場合、最初からやり直す必要がありますが、フィルタを保存すると、個々のフィルタの削除や編集が可能な表などが作成できます。 2要素ベクトルのリストを保存してから、リストを繰り返してデータをフィルタリングすることができます。

+0

返信いただきありがとうございます。あなたはdownloaderHandlerにファイルがありますので、私はその参照をキャッチしませんでした。スコープに関するあなたのコメントで、私は複雑さに同意します。しかし、私が理解していることから、グローバル変数を作成することで選択肢の履歴を保存することができます。私はあなたのバージョンが最後の選択肢しか保存しないと信じています。現在のアプリケーションにグローバル変数を使用してすべての選択肢の履歴をレンダリングできない場合は、すべてのフィルタを保存し、それぞれを別々に反復せずにテキストとフィルタリングされたデータを格納しようとするのではなく、 – DRcod

+0

いいえ、リストを含めて 'reactiveValue'に任意のものを保存することができます。私が間違っていない場合、shinyの '' - ''を使う唯一の理由は、あるユーザのフィルタ履歴が他のユーザのために上書きされるようにするためです。この場合、履歴を含む文字列を編集して保存します。上書きするまではそのまま残ります。また、フィルタリングされたデータを同じ方法で保存して更新し、そこで動作します。私はあなたの最小限の例でそれを試してみました。 –

+0

ありがとうございました! – DRcod

関連する問題