Вопрос или проблема
Доброе утро! Я работаю над разработкой shiny приложения, где пользователи могут выбрать желаемого игрока и стадион, чтобы создать анимационный график домашнего забега. Мой код для графика, пользовательского интерфейса и сервера приведён ниже.
library(tidyverse)
library(gganimate)
library(ggtext)
library(data.table)
library(mlbplotR)
library(GeomMLBStadiums)
library(shiny)
HRPlot_data <- read_csv("HRPlot_data.csv") %>%
select(player_name, batter, des, launch_speed, launch_angle, hit_distance_sc, hc_x_adj, hc_y_adj, HR,
home_team, Opponent, pitcher, fielder_2, fielder_3, fielder_4, fielder_6, fielder_5, fielder_7,
fielder_8, fielder_9) %>%
mutate(x_coord = hc_x_adj * 2.495671, y_coord = hc_y_adj * 2.495671)
HRPlot_ID <- read_csv("HRPlot_ID.csv")
HRPlot_Colors <- load_mlb_teams()
HRPlot_Colors2 <- HRPlot_Colors %>%
mutate(stadium = gsub(" ", "_", tolower(HRPlot_Colors$team_mascot)),
venue = case_when(stadium == "blue_jays" ~ "bluejays",
stadium == "white_sox" ~ "whitesox",
stadium == "red_sox" ~ "redsox", .default = stadium))
HRPlot_data1 <- list(
HRPlot_dataex1 <- list(
HRPlot_dataex2 <- HRPlot_data,
HRPlot_HomeStadium <- HRPlot_Colors2 %>%
select(stadium, team_abbr) %>%
rename(home_team = team_abbr)
) %>% reduce(merge, by = "home_team"),
HRPlot_Colorsex <- HRPlot_Colors2 %>%
select(team_abbr, team_color, team_color2, team_name) %>%
rename(Opponent = team_abbr, color1 = team_color, color2 = team_color2)
) %>% reduce(merge, by = "Opponent")
home_run_animate <- function(name, venue) {
library(GeomMLBStadiums)
library(mlbplotR)
library(gganimate)
library(ggtext)
library(data.table)
library(gifski)
HRPlot_MLBID <- HRPlot_data1 %>% # ID игрока
filter(player_name == name) %>%
pull(batter) %>%
unique()
HRPlot_HomeRun <- HRPlot_data1 %>% # Общее количество домашних забегов игрока
filter(player_name == name) %>%
group_by(player_name) %>%
reframe(HR = n()) %>%
pull(HR)
HRPlot_playerdata <- list(
MorelHR1 <- HRPlot_data1 %>%
filter(player_name == name) %>%
rename(key_mlbam = pitcher),
Pitcher <- HRPlot_ID
) %>% reduce(merge, by = "key_mlbam")
HRPlot_Positions <- list(
z_Catcher <- list(
Catcher <- HRPlot_playerdata %>% select(HR, fielder_2, Opponent, color1, color2) %>% rename(key_mlbam = fielder_2),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "catcher"),
z_FirstBase <-list(
FirstBase <- HRPlot_playerdata %>% select(HR, fielder_3, Opponent, color1, color2) %>% rename(key_mlbam = fielder_3),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "first_base"),
z_SecondBase <- list(
SecondBase <- HRPlot_playerdata %>% select(HR, fielder_4, Opponent, color1, color2) %>% rename(key_mlbam = fielder_4),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "second_base"),
z_Shortstop <- list(
Shortstop <- HRPlot_playerdata %>% select(HR, fielder_6, Opponent, color1, color2) %>% rename(key_mlbam = fielder_6),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "shortstop"),
z_ThirdBase <- list(
ThirdBase <- HRPlot_playerdata %>% select(HR, fielder_5, Opponent, color1, color2) %>% rename(key_mlbam = fielder_5),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "third_base"),
z_LeftField <- list(
LeftField <- HRPlot_playerdata %>% select(HR, fielder_7, Opponent, color1, color2) %>% rename(key_mlbam = fielder_7),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "left_field"),
z_CenterField <- list(
CenterField <- HRPlot_playerdata %>% select(HR, fielder_8, Opponent, color1, color2) %>% rename(key_mlbam = fielder_8),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "center_field"),
z_RightField <- list(
RightField <- HRPlot_playerdata %>% select(HR, fielder_9, Opponent, color1, color2) %>% rename(key_mlbam = fielder_9),
HRPlot_ID) %>% reduce(merge, by = "key_mlbam") %>% mutate(position = "right_field")
) %>% rbindlist() %>%
mutate(fielder_x = case_when(position == "catcher" ~ 0, position == "first_base" ~ 57.5,
position == "second_base" ~ 50, position == "shortstop" ~ -50,
position == "third_base" ~ -57.5, position == "left_field" ~ -130,
position == "center_field" ~ 0, position == "right_field" ~ 130),
fielder_y = case_when(position == "catcher" ~ -20, position == "first_base" ~ 60,
position == "second_base" ~ 120, position == "shortstop" ~ 120,
position == "third_base" ~ 60, position == "left_field" ~ 220,
position == "center_field" ~ 310, position == "right_field" ~ 220))
HRPlot_plot <- HRPlot_playerdata %>%
ggplot(aes(x = x_coord, y = y_coord)) +
geom_segment(aes(x = 0, y = 0, xend = x_coord, yend = y_coord)) +
geom_spraychart(stadium_ids = venue, stadium_transform_coords = T, stadium_segments = "all") +
geom_point(color = "red", size = 3) +
geom_label(data = HRPlot_Positions, aes(x = fielder_x, y = fielder_y, label = player_name2,
color = "white", fill = "black"), fontface = "bold") +
geom_mlb_dot_logos(aes(team_abbr = Opponent), x = 0, y = 210, width = 0.09) +
scale_x_continuous(limits = c(-325, 325)) +
annotate(GeomMLBheads, player_id = HRPlot_MLBID, width = 0.5, x = -225, y = 10) +
geom_rect(aes(xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf), color = "black", fill = NA) +
labs(title = "Количество домашних забегов: {current_frame}",
subtitle = paste("против.", "**{filter(HRPlot_playerdata, HR == current_frame) %>% pull(player_name2) %>% .[[1]]}**", "|",
"**{filter(HRPlot_playerdata, HR == current_frame) %>% pull(launch_speed) %>% .[[1]]}**", "миль/ч |",
"**{filter(HRPlot_playerdata, HR == current_frame) %>% pull(launch_angle) %>% .[[1]]}**", "градусы |",
"**{filter(HRPlot_playerdata, HR == current_frame) %>% pull(hit_distance_sc) %>% .[[1]]}**", "футы"),
caption = "Данные предоставлены MLB Advanced Media | **Стивен Паппас**", x = NULL, y = NULL) +
theme_void() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 20),
plot.subtitle = element_markdown(hjust = 0.5, size = 18),
plot.caption = element_markdown(size = 11, hjust = 0.99)) +
scale_color_identity() +
scale_fill_identity() +
guides(color = "none", fill = "none") +
transition_manual(HR) +
enter_fade() +
ease_aes("linear")
gganimate::animate(HRPlot_plot, fps = 5)
}
HRPlot_datashiny1 <- HRPlot_data1 %>%
group_by(player_name) %>%
reframe(N = n())
HRPlot_datashiny2 <- HRPlot_Colors2 %>%
group_by(venue) %>%
reframe(N = n())
HRPlot_players <- HRPlot_datashiny1$player_name
HRPlot_venues <- HRPlot_datashiny2$venue
HRPlot_ui <- fluidPage(
titlePanel("Анимация домашних забегов"),
sidebarLayout(
sidebarPanel(
selectInput("hitter", "Выберите бьющего:", choices = HRPlot_players),
selectInput("venue", "Выберите стадион:", choices = HRPlot_venues),
actionButton("plotButton", "Создать график")
),
mainPanel(
imageOutput("homeRunPlot")
)
)
)
HRPlot_server <- function(input, output, session) {
observeEvent(input$plotButton, {
req(input$hitter, input$venue)
file_path = tempfile(fileext = ".gif")
anim = home_run_animate(name = input$hitter, venue = input$venue)
anim_save(file_path, anim)
output$homeRunPlot = renderImage({
list(src = file_path, contentType = "image/gif")
}, deleteFile = T)
})
}
shinyApp(ui = HRPlot_ui, server = HRPlot_server)
Этот код предоставляет мне желаемое shiny приложение на моём локальном R, но я сталкиваюсь с проблемами, когда пытаюсь опубликовать его на shinyapps.io. Мне выдает сообщение об ошибке “Произошла ошибка. Приложение не удалось запустить. код выхода 1.” Я считаю, что эта ошибка является способствующим фактором, но не уверен, почему она существует. Я установил рабочий каталог, чтобы получить доступ к папке, содержащей моё shiny приложение.
setwd("C:/Users/sppap/OneDrive/Documents/Home Run Plot")
showLogs()
Ошибка: 'HRPlot_data.csv' не существует в текущем рабочем каталоге ('/srv/connect/apps/homerunshiny').
У кого-нибудь есть идеи, как помочь мне решить эту проблему? Это приложение простое, и я хочу сделать его более сложным. Однако сначала я хочу удостовериться, что оно может работать на shinyapps.io. Спасибо! Желаю вам замечательного дня!
Стивен
Ответ или решение
Ошибки при публикации в ShinyApps.io: Причины и решения
Доброе утро, Стивен!
Спасибо за то, что поделились своим проектом и возникшей проблемой. Ошибка, с которой вы столкнулись, в частности сообщение "An error has occurred. The application failed to start. exit status 1", указывает на сбой в процессе запуска вашего Shiny приложения на платформе shinyapps.io. Давайте разбить проблему на части и рассмотрим возможные причины и решения, чтобы наконец добиться успешной публикации приложения.
1. Проверка зависимостей и библиотек
Прежде всего, убедитесь, что все необходимые библиотеки установлены на вашем локальном компьютере и могут быть загружены при выполнении кода. Ваша программа использует библиотеки tidyverse
, gganimate
, mlbplotR
, и GeomMLBStadiums
. Важно, чтобы они также были доступны на сервере shinyapps.io.
Проверьте их наличие, выполнив команду:
installed.packages()
Если какая-либо из библиотек не установлена, установите её с помощью:
install.packages("имя_пакета")
2. Рабочая директория и файлы данных
Судя по ошибке:
Error: 'HRPlot_data.csv' does not exist in current working directory ('/srv/connect/apps/homerunshiny').
проблема заключается в том, что ваш код пытается загрузить файл HRPlot_data.csv
, но не может его найти, так как файл не загружается на сервер при публикации приложения. В отличие от локального окружения, где вы можете управлять директориями, сервер не может получить доступ к файлам на вашем компьютере.
Решение:
- Переместите необходимые данные (файлы CSV) в отдельную папку внутри вашего проекта Shiny. Убедитесь, что структура вашего проекта такова:
/Home Run Plot/
├── app.R
├── HRPlot_data.csv
├── HRPlot_ID.csv
└── другие_файлы
- Измените путь загрузки в коде, чтобы он искал файлы относительно своего местоположения, например:
HRPlot_data <- read_csv("HRPlot_data.csv")
3. Используйте shiny::addResourcePath()
Если ваши файлы необходимо хранить в определённой папке (например, в папке data
), вы можете использовать функцию addResourcePath()
, чтобы указать путь к этой папке:
shiny::addResourcePath("data", "path/to/your/data/folder")
HRPlot_data <- read_csv("data/HRPlot_data.csv")
4. Использование fileInput()
для загрузки данных
Если вы хотите, чтобы пользователи могли загружать собственные данные, рассмотрите возможность добавления элемента fileInput()
в пользовательский интерфейс:
fileInput("dataFile", "Загрузите файл данных")
Это позволит пользователям загружать файлы при запуске приложения, что также может помочь избежать проблем с отсутствующими файлами.
5. Просмотр логов
Не забудьте использовать функцию showLogs()
для просмотра журналов приложения на shinyapps.io. Это может дать дополнительные подсказки о том, что именно пошло не так при запуске вашего приложения.
6. Общие рекомендации
- Обязательно протестируйте приложение локально после внесения изменений.
- Прочитайте документацию по shinyapps.io, чтобы понять различные требования и ограничения.
- Попробуйте избегать использования абсолютных путей к файлам или зависимостям, опирайтесь на относительные пути.
Если вы выполните все вышеперечисленные шаги, ваш проект должен заработать на shinyapps.io без ошибок. Желаю успехов в разработке более сложных функций вашего приложения! Если появятся дополнительные вопросы, не стесняйтесь спрашивать.
С уважением,
[Ваше Имя]