2017-12-16 5 views
0

Ich verwende Formattable, um eine bedingte Farbformatierung in einer Tabelle in einer glänzenden App zu implementieren. Nehmen wir zum Beispiel an, ich möchte Zellen unter dem Wert 2, grün, über 5, rot und zwischen 2 und 5, orange färben. Ich würde meine Formatierer Funktion wie folgt schreiben:Dynamische Bedingungen in Formattabelle

formatter(
    "span", 
    style = x ~ style(
    color = 'white', 
    'background-color' = 
    ifelse(x > 5, "red", 
     ifelse(x > 2 & x <= 5, "orange", 
     "green")))) 

Aber was ich wirklich tun wollen ist, diese Farbe Schwellenwerte haben, das heißt, 2 und 5, in der Lage sein vom Anwender geändert werden.

Sagen wir also user_low und user_high vom Benutzer definiert werden:

col_format <- 
    formatter(
     "span", 
     style = x ~ style(
     color = 'white', 
     'background-color' = 
     ifelse(x > input$user_high, "red", 
      ifelse(x > input$user_low & x <= input$user_high, "orange", 
      "green")))) 

Wenn ich versuche nun diese Formatierer in formatierbare in meinem glänzenden App zu füttern:

formattable(mtcars, col_format) 

ich folgende Fehlermeldung erhalten :

'col_format' of mode 'function' was not found 

Scheinbar Eingabe $ user_low und Eingabe $ user_high werden nicht ausgewertet und sind ins Tead als Zeichenfolgen im Formatierer behandelt. Ich habe versucht, eval(), eval (parse()), vergeblich.

Irgendwelche Ideen?

+0

Nicht sicher 'formattable' aber dies ist wirklich einfach mit' tableHTML'. Überprüfen Sie [hier] (https://cran.r-project.org/web/packages/tableHTML/vignettes/conditional_column.html). Es funktioniert auch mit glänzend. – LyzandeR

+0

Nizza @ LyzandeR. Ich habe TableHTML nicht gesehen, definitiv ein gutes Backup. Formattable sieht ein bisschen schöner aus, würde es gerne in diesem Rahmen machen, wenn möglich – quantumcatz

Antwort

0

Ihr Code ist fast funktional, aber wenn Sie Eingabeelemente wie input$user_high in einem Ausdruck verwenden möchten, müssen Sie einen reactive verwenden.

Dies, um passieren wird:

ändern
  1. Die Werte der Eingangselemente. (entweder input$user_low oder input$user_high)
  2. Die Spaltenformatierungsbedingung (col_format) wird aktualisiert, da sich ihre Abhängigkeit geändert hat.
  3. Die dataTableOutput wird neu gerendert, weil sie von col_format abhängt.

Beispielcode:

library(shiny) 
library(formattable) 
library(DT) 

ui <- fluidPage(
    sidebarLayout(
    sidebarPanel(
     numericInput("user_low", "User low", value = 2, min = 1, max = 5), 
     numericInput("user_high", "User high", value = 8, min = 6, max = 10) 
    ), 

    mainPanel(
     DT::dataTableOutput("table") 
    ) 
) 
) 

server <- function(input, output) { 
    output$table <- DT::renderDataTable({ 
    as.datatable(formattable(mtcars, list(
     cyl = col_format() 
    ))) 
    }) 

    col_format <- reactive({ 
    formatter(
     "span", 
     style = x ~ style(
     color = 'white', 
     'background-color' = 
      ifelse(x > input$user_high, "red", 
       ifelse(x > input$user_low & x <= input$user_high, "orange", 
         "green")))) 
    }) 

} 

shinyApp(ui, server) 

bearbeiten: die Formatierungs zu jeder Spalte (wie pro Ihren Kommentar) anwenden zu können, können Sie lapply verwenden, wie in der in den dynamisch zu erzeugen Formatierer Abschnitt gezeigt Formattable vignette. Der folgende Code wendet die Formatierung auf den gesamten Datensatz an.

Code:

output$table <- DT::renderDataTable({ 
    as.datatable(formattable(mtcars, lapply(1:ncol(mtcars), function(col) { 
    area(row = 1:nrow(mtcars), col) ~ col_format() 
    }))) 
}) 
+0

Ah! Danke für das @GyD. Ich habe tatsächlich versucht, den Formatierer in einen reaktiven Code einzufügen, und es hat nicht funktioniert, aber ich merke jetzt, dass es daran lag, dass ich den Formatierer auf jede Spalte anwenden wollte (nicht nur "Zyl", wie in deiner Antwort). Ich hätte das wahrscheinlich erwähnen sollen. Ich werde die Frage als beantwortet markieren, aber wenn Sie irgendeine Idee haben, wie man den Formatierer auf jede Spalte von mtcars anwendet, würde es sehr geschätzt werden! – quantumcatz

+0

@quantumcatz können Sie 'lapply' dafür verwenden, da Sie' formattable' eine Liste zur Verfügung stellen müssen. Siehe meine bearbeitete Antwort für Details. – GyD

+0

Funktioniert perfekt, danke @GyD. – quantumcatz