Spaces:
Sleeping
Sleeping
| 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) |