sugitora's picture
Update app.R
7951d01 verified
library(shiny)
library(ggplot2)
library(dplyr)
library(tidyr)
ui <- fluidPage(
titlePanel("クライアント型電子計算機の分析可視化(連動型)"),
sidebarLayout(
sidebarPanel(
# 残存関数パラメータ
sliderInput("alpha", "残存関数のパラメータ alpha:",
min = 1, max = 4, value = 2.58, step = 0.01),
sliderInput("lambda", "残存関数のパラメータ lambda:",
min = 5, max = 15, value = 8.0, step = 0.1),
# ストック推計関連パラメータ
sliderInput("base_shipment", "基準年出荷台数(万台):",
min = 800, max = 1200, value = 1000, step = 10),
sliderInput("decline_rate", "出荷台数減少率(%/年):",
min = 0, max = 5, value = 2, step = 0.1),
# TEC関連パラメータ
sliderInput("base_tec", "基準TEC値(kWh):",
min = 15, max = 35, value = 25, step = 0.5),
sliderInput("tec_improvement", "TEC改善率(%/年):",
min = 0, max = 10, value = 3, step = 0.1),
# TEC分布共通インタラクティブ項目
sliderInput("screen_min", "画面サイズ(最小)",
min = 8, max = 14.9, value = 8, step = 0.1),
sliderInput("screen_max", "画面サイズ(最大)",
min = 15.1, max = 18, value = 18, step = 0.1),
numericInput("mean_tec", "TEC平均値", value = 20, min = 0),
numericInput("sd_tec", "TEC標準偏差", value = 5, min = 0.1),
checkboxInput("show_medians", "中央値ラベルを表示", value = TRUE),
checkboxInput("show_vline", "15インチ区切り線を表示", value = TRUE)
),
mainPanel(
tabsetPanel(
tabPanel("残存関数", plotOutput("residualPlot")),
tabPanel("ストック推計", plotOutput("stockPlot")),
tabPanel("エネルギー消費量", plotOutput("energyPlot")),
tabPanel("TEC分布(ノートPC)", plotOutput("tecNotePlot")),
tabPanel("TEC分布(Pスコア)", plotOutput("tecPscorePlot")),
tabPanel("TEC分布(デスクトップ)", plotOutput("tecDesktopPlot")),
tabPanel("TEC分布(分離型PC)", plotOutput("tecSplitPlot")),
tabPanel("パラメータ感度分析", plotOutput("sensitivityPlot"))
)
)
)
)
server <- function(input, output) {
# Survival function calculation
residual_function <- reactive({
n <- 0:30
residual_rate <- exp(- (n / input$lambda)^input$alpha)
data.frame(Year = n, ResidualRate = residual_rate)
})
# Stock estimation calculation (linked with survival function)
stock_estimation <- reactive({
years <- 2000:2030
n_years <- length(years)
# Actual data (2000-2022)
actual_stock <- c(55000000, 61000000, 67000000, 73000000, 80000000, 86000000,
91000000, 96000000, 101000000, 106000000, 111000000, 115000000,
118000000, 120000000, 121000000, 120000000, 116000000, 113000000,
112000000, 111000000, 108000000, 107000000, 106000000)
# Estimated data (2023-2030) - Based on survival function parameters
estimated_stock <- numeric(8)
base_year_stock <- 106000000 # Based on 2022 value
for (i in 1:8) {
# Stock estimation using survival function
age_distribution <- residual_function()
survival_rate <- mean(age_distribution$ResidualRate[1:min(i+5, nrow(age_distribution))])
# Consider shipment decline
shipment_factor <- (1 - input$decline_rate/100)^i
estimated_stock[i] <- base_year_stock * survival_rate * shipment_factor
}
# Create data frame
data.frame(
Year = years,
Actual = c(actual_stock, rep(NA, 8)),
Estimated = c(rep(NA, 23), estimated_stock)
)
})
# Energy consumption calculation (linked with stock estimation and TEC values)
energy_consumption <- reactive({
stock_data <- stock_estimation()
years <- 2006:2030
# Actual data (2006-2022)
actual_consumption <- c(10000, 10300, 10400, 10200, 10100, 10000, 9800, 9400, 9200, 8900,
8500, 8100, 7700, 7200, 6800, 6300, 6000)
# Estimated data (2023-2030) - Based on stock and TEC improvement
estimated_consumption <- numeric(8)
for (i in 1:8) {
year_idx <- 23 + i # Index for 2023 onwards in stock_data
stock_value <- stock_data$Estimated[year_idx]
if (!is.na(stock_value)) {
# Consider TEC improvement
tec_factor <- input$base_tec * (1 - input$tec_improvement/100)^i
# Energy consumption = Stock × TEC × Operating hours factor
# Unit conversion: units × kWh → GWh
operating_hours_factor <- 2000 # Annual operating hours
estimated_consumption[i] <- (stock_value * tec_factor * operating_hours_factor) / 1e9
} else {
estimated_consumption[i] <- NA
}
}
data.frame(
Year = years,
Actual = c(actual_consumption, rep(NA, 8)),
Estimated = c(rep(NA, 17), estimated_consumption)
)
})
# Plot outputs
output$residualPlot <- renderPlot({
df <- residual_function()
ggplot(df, aes(x = Year, y = ResidualRate)) +
geom_line(color = "darkorange", size = 1.2) +
geom_point(color = "darkorange", size = 2) +
labs(title = "Survival Function",
subtitle = paste("alpha =", input$alpha, ", lambda =", input$lambda),
x = "Years (n)", y = "Survival Rate") +
theme_minimal() +
ylim(0, 1.2) +
theme(text = element_text(family = "sans"))
})
output$stockPlot <- renderPlot({
df <- stock_estimation()
df_long <- df %>%
mutate(Year = as.character(Year)) %>%
pivot_longer(cols = c(Actual, Estimated), names_to = "Category", values_to = "Stock") %>%
filter(!is.na(Stock))
ggplot(df_long, aes(x = Year, y = Stock, fill = Category)) +
geom_col(position = "dodge") +
scale_fill_manual(values = c("Actual" = "steelblue", "Estimated" = "darkorange")) +
scale_y_continuous(labels = scales::comma_format()) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
text = element_text(family = "sans")) +
labs(title = "Stock Estimation (Linked with Survival Function)",
subtitle = paste("Decline Rate:", input$decline_rate, "%/year"),
x = "Year", y = "Stock (units)")
})
output$energyPlot <- renderPlot({
data <- energy_consumption()
data_long <- data %>%
pivot_longer(cols = c("Actual", "Estimated"), names_to = "Category", values_to = "Consumption") %>%
filter(!is.na(Consumption))
ggplot(data_long, aes(x = Year, y = Consumption, fill = Category)) +
geom_col(position = "dodge") +
scale_fill_manual(values = c("Actual" = "steelblue", "Estimated" = "darkorange")) +
scale_y_continuous(labels = scales::comma_format()) +
labs(title = "Energy Consumption Trends (Linked with Stock & TEC)",
subtitle = paste("TEC Improvement Rate:", input$tec_improvement, "%/year, Base TEC:", input$base_tec, "kWh"),
x = "Year", y = "GWh/year") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
text = element_text(family = "sans"))
})
# Sensitivity analysis plot
output$sensitivityPlot <- renderPlot({
# Current parameters for 2030 estimation
current_stock <- tail(stock_estimation()$Estimated[!is.na(stock_estimation()$Estimated)], 1)
current_energy <- tail(energy_consumption()$Estimated[!is.na(energy_consumption()$Estimated)], 1)
# Parameter ranges for sensitivity analysis
alpha_range <- seq(1.5, 3.5, 0.1)
lambda_range <- seq(6, 12, 0.5)
sensitivity_data <- expand.grid(alpha = alpha_range, lambda = lambda_range)
sensitivity_data$stock_2030 <- NA
sensitivity_data$energy_2030 <- NA
for (i in 1:nrow(sensitivity_data)) {
# Simplified calculation (streamlined calculation logic)
alpha_temp <- sensitivity_data$alpha[i]
lambda_temp <- sensitivity_data$lambda[i]
survival_rate <- exp(-(8/lambda_temp)^alpha_temp) # 8-year survival rate
stock_factor <- (1 - input$decline_rate/100)^8
sensitivity_data$stock_2030[i] <- 106000000 * survival_rate * stock_factor
sensitivity_data$energy_2030[i] <- (sensitivity_data$stock_2030[i] *
input$base_tec * (1 - input$tec_improvement/100)^8 * 2000) / 1e9
}
ggplot(sensitivity_data, aes(x = alpha, y = lambda, fill = energy_2030)) +
geom_tile() +
scale_fill_gradient2(low = "blue", mid = "white", high = "red",
midpoint = median(sensitivity_data$energy_2030, na.rm = TRUE)) +
geom_point(aes(x = input$alpha, y = input$lambda),
color = "black", size = 4, shape = 21, fill = "yellow") +
labs(title = "Parameter Sensitivity Analysis (2030 Energy Consumption)",
subtitle = "Yellow dot: Current setting",
x = "Alpha", y = "Lambda", fill = "GWh/year") +
theme_minimal()
})
# Existing TEC plots
output$tecNotePlot <- renderPlot({
set.seed(123)
screen_size <- c(runif(25, input$screen_min, min(14.9, input$screen_max)),
runif(15, max(15.1, input$screen_min), input$screen_max))
tec_value <- c(rnorm(25, input$mean_tec - 5, input$sd_tec),
rnorm(15, input$mean_tec + 5, input$sd_tec))
df1 <- data.frame(ScreenSize = screen_size, TEC = tec_value)
medians1 <- data.frame(
ScreenSize = c(mean(c(input$screen_min, 14.9)), mean(c(15.1, input$screen_max))),
TEC = c(input$mean_tec - 5, input$mean_tec + 5),
Label = sprintf("%.2f", c(input$mean_tec - 5, input$mean_tec + 5))
)
p <- ggplot(df1, aes(x = ScreenSize, y = TEC)) +
geom_point(color = "blue") +
labs(title = "TEC Distribution: Notebook PC (Category J・K)", x = "Screen Size", y = "TEC[kWh]") +
theme_minimal()
if (input$show_vline) {
p <- p + geom_vline(xintercept = 15, linetype = "dashed")
}
if (input$show_medians) {
p <- p + geom_text(data = medians1, aes(label = Label), vjust = -1, color = "red", size = 4)
}
p
})
output$tecPscorePlot <- renderPlot({
set.seed(124)
df2 <- data.frame(P_score = runif(30, 8, 13), TEC = rnorm(30, 20, 5))
ggplot(df2, aes(x = P_score, y = TEC)) +
geom_point(color = "darkgreen") +
geom_segment(aes(x = 10.5, xend = 12.5, y = 11.34, yend = 11.34), color = "red") +
annotate("text", x = 12.7, y = 11.34, label = "11.34") +
labs(title = "TEC Distribution: P-score 8 or Higher (Category L)", x = "P-score", y = "TEC[kWh]") +
theme_minimal()
})
output$tecDesktopPlot <- renderPlot({
set.seed(125)
df3 <- data.frame(P_score = runif(40, 2, 15), TEC = runif(40, 30, 180))
ggplot(df3, aes(x = P_score, y = TEC)) +
geom_point() +
geom_vline(xintercept = 8, linetype = "dashed") +
annotate("text", x = 5, y = 180, label = "Category M") +
annotate("text", x = 12, y = 180, label = "Category N") +
geom_segment(aes(x = 3, xend = 7, y = 39.87, yend = 39.87), color = "red") +
geom_segment(aes(x = 10, xend = 14, y = 53.32, yend = 53.32), color = "red") +
annotate("text", x = 7.1, y = 39.87, label = "39.87") +
annotate("text", x = 14.1, y = 53.32, label = "53.32") +
labs(title = "TEC Distribution: Integrated Desktop (M/N)", x = "P-score", y = "TEC[kWh]") +
theme_minimal()
})
output$tecSplitPlot <- renderPlot({
set.seed(126)
df4 <- data.frame(Volume = runif(40, 0, 20), TEC = runif(40, 20, 140))
ggplot(df4, aes(x = Volume, y = TEC)) +
geom_point() +
geom_vline(xintercept = 10, linetype = "dashed") +
annotate("text", x = 4, y = 140, label = "Category O") +
annotate("text", x = 14, y = 140, label = "Category P") +
geom_segment(aes(x = 3, xend = 8, y = 29.55, yend = 29.55), color = "red") +
geom_segment(aes(x = 11, xend = 15, y = 31.33, yend = 31.33), color = "red") +
annotate("text", x = 8.1, y = 29.55, label = "29.55") +
annotate("text", x = 15.1, y = 31.33, label = "31.33") +
labs(title = "TEC Distribution: Separate PC (O/P)", x = "Volume[L]", y = "TEC[kWh]") +
theme_minimal()
})
}
shinyApp(ui = ui, server = server)