library(shiny)
library(readxl)
## Warning: package 'readxl' was built under R version 4.4.3
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(lubridate)
##
## Adjuntando el paquete: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(plotly)
## Warning: package 'plotly' was built under R version 4.4.3
## Cargando paquete requerido: ggplot2
##
## Adjuntando el paquete: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
# --- 1. Cargar y procesar datos ---
ruta <- "C:/Users/juan1/OneDrive/Documents/Semillero/datos_invernadero/Copia de med_new.xlsx"
datos_raw <- read_excel(ruta)
## New names:
## • `` -> `...30`
datos <- datos_raw %>%
mutate(
Fecha_chr = as.character(Fecha),
Hora_chr = as.character(Hora),
Tiempo = dmy_hm(paste(Fecha_chr, Hora_chr)),
Radiacion_In = as.numeric(`Radiacion_In(W/m2)`),
Radiacion_Out = as.numeric(`Radiacion_Out(W/m2)`)
) %>%
filter(!is.na(Tiempo), !is.na(Radiacion_In)) %>%
select(Tiempo, Radiacion_In, Radiacion_Out)
# --- 2. Interfaz de Usuario ---
ui <- fluidPage(
titlePanel("🌞 Radiación Invernadero vs Exterior"),
sidebarLayout(
sidebarPanel(
dateRangeInput("rango", "Selecciona el rango de fechas:",
start = min(datos$Tiempo),
end = max(datos$Tiempo),
min = min(datos$Tiempo),
max = max(datos$Tiempo),
format = "yyyy-mm-dd"),
selectInput("resolucion", "Agrupar por:",
choices = c("Cada 5 min" = "5min",
"Cada hora" = "1h",
"Cada 3 horas" = "3h",
"Diario" = "diario",
"Semanal" = "semanal",
"Mensual" = "mensual")),
checkboxInput("mostrar_out", "Mostrar Radiación Exterior", value = FALSE)
),
mainPanel(
plotlyOutput("grafico", height = "600px"),
h4("📊 Resumen EstadÃstico (sin ceros)"),
tableOutput("resumen")
)
)
)
# --- 3. Lógica del Servidor ---
server <- function(input, output) {
datos_filtrados <- reactive({
req(input$rango)
datos %>%
filter(Tiempo >= as.POSIXct(input$rango[1]) & Tiempo <= as.POSIXct(input$rango[2])) %>%
mutate(Grupo = case_when(
input$resolucion == "5min" ~ floor_date(Tiempo, "5 minutes"),
input$resolucion == "1h" ~ floor_date(Tiempo, "1 hour"),
input$resolucion == "3h" ~ floor_date(Tiempo, "3 hours"),
input$resolucion == "diario" ~ as.Date(Tiempo),
input$resolucion == "semanal" ~ floor_date(Tiempo, "week"),
input$resolucion == "mensual" ~ floor_date(Tiempo, "month")
)) %>%
group_by(Grupo) %>%
summarise(
Radiacion_In = mean(Radiacion_In, na.rm = TRUE),
Radiacion_Out = mean(Radiacion_Out, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
tooltip_in = paste0("Fecha: ", Grupo, "<br>Radiación In: ", round(Radiacion_In, 2), " W/m²"),
tooltip_out = paste0("Fecha: ", Grupo, "<br>Radiación Out: ", round(Radiacion_Out, 2), " W/m²")
)
})
output$grafico <- renderPlotly({
df <- datos_filtrados()
fig <- plot_ly(df, x = ~Grupo) %>%
add_trace(y = ~Radiacion_In, type = 'scatter', mode = 'lines+markers',
name = "Radiación Invernadero",
line = list(color = "darkblue"),
marker = list(color = "orange", size = 5),
text = ~tooltip_in, hoverinfo = "text")
if (input$mostrar_out) {
fig <- fig %>%
add_trace(y = ~Radiacion_Out, type = 'scatter', mode = 'lines+markers',
name = "Radiación Exterior",
line = list(color = "forestgreen", dash = "dash"),
marker = list(color = "green", size = 5),
text = ~tooltip_out, hoverinfo = "text")
}
fig %>% layout(
title = "Radiación Agrupada por Resolución",
xaxis = list(title = "Fecha / Hora"),
yaxis = list(title = "Radiación (W/m²)")
)
})
output$resumen <- renderTable({
df <- datos_filtrados()
df_in <- df %>% filter(Radiacion_In > 0)
resumen <- df_in %>%
summarise(
Promedio_In = round(mean(Radiacion_In, na.rm = TRUE), 2),
Maximo_In = round(max(Radiacion_In, na.rm = TRUE), 2),
Minimo_In = round(min(Radiacion_In, na.rm = TRUE), 2),
Acumulado_In = round(sum(Radiacion_In, na.rm = TRUE), 2)
)
if (input$mostrar_out) {
df_out <- df %>% filter(Radiacion_Out > 0)
resumen_out <- df_out %>%
summarise(
Promedio_Out = round(mean(Radiacion_Out, na.rm = TRUE), 2),
Maximo_Out = round(max(Radiacion_Out, na.rm = TRUE), 2),
Minimo_Out = round(min(Radiacion_Out, na.rm = TRUE), 2),
Acumulado_Out = round(sum(Radiacion_Out, na.rm = TRUE), 2)
)
resumen <- bind_cols(resumen, resumen_out)
}
resumen
})
}
# --- 4. Ejecutar la Aplicación ---
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents