Encuentro 8 - capítulo 12
Framework del paquete rlang
que permite controlar cómo se evalúan las expresiones y variables en tu código cuando están dentro de funciones del tidyverse.
Es una variable de programación que creás con <- en el entorno de R.
Vive en el entorno de ejecución, no dentro de un df.
Se accede directamente por su nombre o desde un input en Shiny, como input$var.
Es una variable estadística (columna que forma parte de un df).
Vive dentro de un objeto de tipo tabla (df o tibble).
Se accede usando $, [[ ]], o dentro de funciones del tidyverse (gracias al data masking).
Objetivo:
diamods
por la columna o variable seleccionada por el usuario.variable_ent <- "carat"
num_vars <- c("carat", "depth", "table", "price", "x", "y", "z")
ui <- fluidPage(
selectInput("var", "Variable", choices = num_vars),
numericInput("min", "Minimum", value = 1),
tableOutput("output")
)
server <- function(input, output, session) {
data <- reactive(diamonds %>%
filter(variable_ent > 5))
output$output <- renderTable(head(data()))
}
shinyApp(ui, server)
num_vars <- c("carat", "depth", "table", "price", "x", "y", "z")
ui <- fluidPage(
selectInput("var", "Variable", choices = num_vars),
numericInput("min", "Minimum", value = 1),
tableOutput("output")
)
server <- function(input, output, session) {
data <- reactive(diamonds %>%
filter("carat" > 5))
output$output <- renderTable(head(data()))
}
shinyApp(ui, server)
La variable de datos (carat) está almacenada en una variable de entorno (input$var), por lo que necesitamos indicarle a filter
explícitamente como recuperarla del df.
La forma de hacerlo varía según si estamos usando data-masking
o tidy-selection
.
¿Qué es?
¿Dónde se usa?
filter()
, mutate()
, summarise()
, etc.# A tibble: 17,502 × 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 1.17 Very Good J I1 60.2 61 2774 6.83 6.9 4.13
2 1.01 Premium F I1 61.8 60 2781 6.39 6.36 3.94
3 1.01 Fair E I1 64.5 58 2788 6.29 6.21 4.03
4 1.01 Premium H SI2 62.7 59 2788 6.31 6.22 3.93
5 1.05 Very Good J SI2 63.2 56 2789 6.49 6.45 4.09
6 1.05 Fair J SI2 65.8 59 2789 6.41 6.27 4.18
7 1.01 Fair E SI2 67.4 60 2797 6.19 6.05 4.13
8 1.04 Premium G I1 62.2 58 2801 6.46 6.41 4
9 1.2 Fair F I1 64.6 56 2809 6.73 6.66 4.33
10 1.02 Premium G I1 60.3 58 2815 6.55 6.5 3.94
# ℹ 17,492 more rows
Dentro de funciones con data-masking se puede usar .data
o .env
para explicitar del tipo de variable que se trata.
# A tibble: 17,502 × 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 1.17 Very Good J I1 60.2 61 2774 6.83 6.9 4.13
2 1.01 Premium F I1 61.8 60 2781 6.39 6.36 3.94
3 1.01 Fair E I1 64.5 58 2788 6.29 6.21 4.03
4 1.01 Premium H SI2 62.7 59 2788 6.31 6.22 3.93
5 1.05 Very Good J SI2 63.2 56 2789 6.49 6.45 4.09
6 1.05 Fair J SI2 65.8 59 2789 6.41 6.27 4.18
7 1.01 Fair E SI2 67.4 60 2797 6.19 6.05 4.13
8 1.04 Premium G I1 62.2 58 2801 6.46 6.41 4
9 1.2 Fair F I1 64.6 56 2809 6.73 6.66 4.33
10 1.02 Premium G I1 60.3 58 2815 6.55 6.5 3.94
# ℹ 17,492 more rows
.data
y .env
pueden combinarse con $
y [[]]
# A tibble: 17,502 × 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 1.17 Very Good J I1 60.2 61 2774 6.83 6.9 4.13
2 1.01 Premium F I1 61.8 60 2781 6.39 6.36 3.94
3 1.01 Fair E I1 64.5 58 2788 6.29 6.21 4.03
4 1.01 Premium H SI2 62.7 59 2788 6.31 6.22 3.93
5 1.05 Very Good J SI2 63.2 56 2789 6.49 6.45 4.09
6 1.05 Fair J SI2 65.8 59 2789 6.41 6.27 4.18
7 1.01 Fair E SI2 67.4 60 2797 6.19 6.05 4.13
8 1.04 Premium G I1 62.2 58 2801 6.46 6.41 4
9 1.2 Fair F I1 64.6 56 2809 6.73 6.66 4.33
10 1.02 Premium G I1 60.3 58 2815 6.55 6.5 3.94
# ℹ 17,492 more rows
num_vars <- c("carat", "depth", "table", "price", "x", "y", "z")
ui <- fluidPage(
selectInput("var", "Variable", choices = num_vars),
numericInput("min", "Minimum", value = 1),
tableOutput("output")
)
server <- function(input, output, session) {
data <- reactive(diamonds %>%
filter(.data[[input$var]] > .env$input$min))
output$output <- renderTable(head(data()))
}
shinyApp(ui, server)
ui <- fluidPage(
selectInput("x", "X variable", choices = names(iris)),
selectInput("y", "Y variable", choices = names(iris)),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
iris %>%
ggplot(aes(input$x, input$y)) +
geom_point()
}, res = 96)
}
shinyApp(ui, server)
ui <- fluidPage(
selectInput("x", "X variable", choices = names(iris)),
selectInput("y", "Y variable", choices = names(iris)),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
iris %>%
ggplot(aes(.data[[input$x]], .data[[input$y]])) +
geom_point()
}, res = 96)
}
shinyApp(ui, server)
ui <- fluidPage(
fileInput("data", "Datos", accept = ".csv"),
selectInput("var", "Variable", character()),
numericInput("min", "Mínimo", 1, min = 0, step = 1),
tableOutput("output")
)
server <- function(input, output, session) {
data <- reactive({
req(input$data)
vroom::vroom(input$data$datapath)
})
observeEvent(data(), {
updateSelectInput(session, "var", choices = names(data()))
})
observeEvent(input$var, {
val <- data()[[input$var]]
updateNumericInput(session, "min", value = min(val))
})
output$output <- renderTable({
req(input$var)
data() %>%
filter(.data[[input$var]] > input$min) %>%
arrange(.data[[input$var]]) %>%
head(10)
})
}
shinyApp(ui, server)
ui <- fluidPage(
fileInput("data", "Datos", accept = ".csv"),
selectInput("var", "Variable", character()),
numericInput("min", "Mínimo", 1, min = 0, step = 1),
tableOutput("output")
)
server <- function(input, output, session) {
data <- reactive({
req(input$data)
vroom::vroom(input$data$datapath)
})
observeEvent(data(), {
updateSelectInput(session, "var", choices = names(data()))
})
observeEvent(input$var, {
val <- data()[[input$var]]
updateNumericInput(session, "min", value = min(val))
})
output$output <- renderTable({
req(input$var)
data() %>%
filter(.data[[input$var]] > .env$input$min) %>%
arrange(.data[[input$var]]) %>%
head(10)
})
}
shinyApp(ui, server)
¿Qué es? Sintaxis para seleccionar columnas de un data frame, basándose en su nombre, posición o tipo. Es una extensión del data masking, pero con una semántica orientada a selección.
¿Dónde se usa? En funciones como select()
, across()
, pivot_longer()
, pivot_wider()
, separate()
, extract()
y unite()
.
any_of()
o all_of()
.all_of()
generará un error, mientras que any_of()
lo ignorará silenciosamente.across()
permite pasar un vector de caracteres con nombres de variables en funciones que usan enmascaramiento de datos.
Resulta útil en funciones como group_by()
o distinct()
, para aplicarlas a múltiples columnas.
ui <- fluidPage(
selectInput("vars", "Variables", names(mtcars), multiple = TRUE),
tableOutput("count")
)
server <- function(input, output, session) {
output$count <- renderTable({
req(input$vars)
mtcars %>%
group_by(across(all_of(input$vars))) %>%
summarise(n = n(), .groups = "drop")
})
}
shinyApp(ui, server)
across()
tipicamente lleva 1 o 2 argumentos:
Variables a seleccionar.
Función o lista de funciones a aplicar.
ui <- fluidPage(
selectInput("vars_g", "Group by", names(mtcars), multiple = TRUE),
selectInput("vars_s", "Summarise", names(mtcars), multiple = TRUE),
tableOutput("data")
)
server <- function(input, output, session) {
output$data <- renderTable({
mtcars %>%
group_by(across(all_of(input$vars_g))) %>%
summarise(across(all_of(input$vars_s), mean), n = n())
})
}
shinyApp(ui, server)