library(shiny)
library(shinydashboard)
library(DT)
dashboard_ui <- dashboardPage(
dashboardHeader(title = "企業分析ダッシュボード"),
dashboardSidebar(
sidebarMenu(
menuItem("概要", tabName = "overview", icon = icon("dashboard")),
menuItem("詳細分析", tabName = "analysis", icon = icon("chart-line")),
menuItem("データテーブル", tabName = "data", icon = icon("table"))
),
div(style = "padding: 20px;",
h4("フィルタ設定"),
selectInput(
inputId = "industry_filter",
label = "業界選択:",
choices = c("すべて" = "all", "IT", "製造業", "金融", "小売", "サービス"),
selected = "all",
multiple = TRUE
),
sliderInput(
inputId = "revenue_range",
label = "売上範囲(百万円):",
min = 0,
max = 5000,
value = c(0, 5000),
step = 100
),
sliderInput(
inputId = "employee_range",
label = "従業員数範囲:",
min = 1,
max = 1000,
value = c(1, 1000),
step = 10
),
checkboxInput(
inputId = "show_trend",
label = "トレンドライン表示",
value = TRUE
),
actionButton(
inputId = "refresh_data",
label = "データ更新",
icon = icon("refresh"),
class = "btn-primary"
)
)
),
dashboardBody(
tags$head(
tags$style(HTML("
.content-wrapper, .right-side {
background-color: #f4f4f4;
}
.main-header .logo {
background-color: #3c8dbc !important;
}
.skin-blue .main-header .navbar {
background-color: #3c8dbc !important;
}
"))
),
tabItems(
tabItem(
tabName = "overview",
fluidRow(
valueBoxOutput("total_companies", width = 3),
valueBoxOutput("avg_revenue", width = 3),
valueBoxOutput("avg_employees", width = 3),
valueBoxOutput("avg_profit", width = 3)
),
fluidRow(
box(
title = "業界別売上分布",
status = "primary",
solidHeader = TRUE,
width = 8,
plotlyOutput("industry_plot", height = "400px")
),
box(
title = "企業規模分布",
status = "success",
solidHeader = TRUE,
width = 4,
plotlyOutput("size_plot", height = "400px")
)
)
),
tabItem(
tabName = "analysis",
fluidRow(
box(
title = "企業パフォーマンス散布図",
status = "primary",
solidHeader = TRUE,
width = 12,
plotlyOutput("scatter_plot", height = "500px")
)
),
fluidRow(
box(
title = "時系列トレンド",
status = "info",
solidHeader = TRUE,
width = 6,
plotlyOutput("trend_plot", height = "350px")
),
box(
title = "相関分析",
status = "warning",
solidHeader = TRUE,
width = 6,
plotlyOutput("correlation_plot", height = "350px")
)
)
),
tabItem(
tabName = "data",
fluidRow(
box(
title = "企業データテーブル",
status = "primary",
solidHeader = TRUE,
width = 12,
div(style = "margin-bottom: 20px;",
downloadButton("download_data", "CSVダウンロード", class = "btn-success")
),
DT::dataTableOutput("data_table")
)
)
)
)
)
)
dashboard_server <- function(input, output, session) {
filtered_data <- reactive({
data <- interactive_data
if (!is.null(input$industry_filter) && !"all" %in% input$industry_filter) {
data <- data %>% filter(industry %in% input$industry_filter)
}
data <- data %>%
filter(
revenue >= input$revenue_range[1],
revenue <= input$revenue_range[2],
employees >= input$employee_range[1],
employees <= input$employee_range[2]
)
return(data)
})
output$total_companies <- renderValueBox({
valueBox(
value = nrow(filtered_data()),
subtitle = "総企業数",
icon = icon("building"),
color = "blue"
)
})
output$avg_revenue <- renderValueBox({
valueBox(
value = paste0("¥", round(mean(filtered_data()$revenue)), "M"),
subtitle = "平均売上",
icon = icon("yen-sign"),
color = "green"
)
})
output$avg_employees <- renderValueBox({
valueBox(
value = round(mean(filtered_data()$employees)),
subtitle = "平均従業員数",
icon = icon("users"),
color = "yellow"
)
})
output$avg_profit <- renderValueBox({
valueBox(
value = paste0(round(mean(filtered_data()$profit_margin), 1), "%"),
subtitle = "平均利益率",
icon = icon("chart-line"),
color = "red"
)
})
output$scatter_plot <- renderPlotly({
p <- filtered_data() %>%
plot_ly(
x = ~revenue,
y = ~profit_margin,
color = ~industry,
size = ~employees,
text = ~company_name,
type = "scatter",
mode = "markers",
hovertemplate = "<b>%{text}</b><br>売上: ¥%{x:,.0f}M<br>利益率: %{y:.1f}%<extra></extra>"
) %>%
layout(
title = "売上 vs 利益率",
xaxis = list(title = "売上高(百万円)"),
yaxis = list(title = "利益率(%)")
)
if (input$show_trend) {
p <- p %>% add_lines(
x = ~revenue,
y = fitted(lm(profit_margin ~ revenue, data = filtered_data())),
line = list(color = "red", width = 2),
name = "トレンドライン",
hoverinfo = "skip"
)
}
p
})
output$data_table <- DT::renderDataTable({
filtered_data() %>%
select(company_name, industry, revenue, employees, profit_margin, satisfaction) %>%
DT::datatable(
options = list(
pageLength = 15,
scrollX = TRUE,
searching = TRUE
),
colnames = c("企業名", "業界", "売上(M¥)", "従業員数", "利益率(%)", "満足度")
) %>%
DT::formatCurrency("revenue", currency = "¥", mark = ",") %>%
DT::formatPercentage("profit_margin", digits = 1)
})
output$download_data <- downloadHandler(
filename = function() {
paste("企業データ_", Sys.Date(), ".csv", sep = "")
},
content = function(file) {
write.csv(filtered_data(), file, row.names = FALSE)
}
)
}
app_config <- list(
ui = dashboard_ui,
server = dashboard_server,
options = list(port = 3838)
)
print("Shinyダッシュボードアプリケーションが設定されました")
print("実行コマンド: shinyApp(ui = dashboard_ui, server = dashboard_server)")