На днях в официальном блоге проекта RStudio было объявлено о выходе их нового продукта - пакета Shiny ("сияющий"), предназначенного для создания интерактивных веб-приложений на базе R. Это не первая разработка такого рода - существует несколько пакетов для создания пользовательских интерфейсов и веб-приложений на основе R (например, tcltk, RGtk2, rpanel, gWidgets, gWidgetsWWW2, и другие). Однако, как утверждают разработчики, Shiny отличается особой простотой, с которой пользователи могут создавать свои приложения (в частности, не требуется знания HTML и/или Java). В этом сообщении я приведу небольшой пример, демонстрирующий возможности Shiny.
В настоящее время пакет Shiny не опубликован на сайте CRAN и поэтому для его инсталляции рекомендуется выполнить следующие команды (предполагается, что во время инсталляции Ваш компьютер подключен к Internet):
В простейшем виде приложение, созданное при помощи Shiny, состоит из двух файлов, которые хранятся в одной папке. Один из этих обязательных файлов (должен иметь имя ui.R) содержит определения элементов пользовательского интерфейса; второй обязательный файл - server.R - содержит скрипт, определяющий работу сервера.
"Скелет" файла ui.R выглядит следующим образом:
"Скелет" файла, контролирующего работу сервера (server.R), выглядит так:
В качестве примера я приведу код приложения, которое будет строить диаграмму размахов по данным о длине раковины моллюска Dreissena polymorpha в трех озерах Беларуси, обследованных в мае, июле и сентябре 2003 г. (Mastitsky 2012; файл с данными, полученными в ходе этого исследования, хранится на сайте figshare). У пользователя будет возможность выбирать озеро, для которого он/она желает отобразить сезонную динамику размеров раковины моллюска. (Примечание: интерфейс приложения будет выполнен на английском языке. Я пока не проверял, "дружит" ли Shiny с кириллицей, но в принципе проблем быть не должно).
У себя на компьютере я создал папку с названием dreissena_app (по адресу D:\dreissena_app) и поместил в нее два упомянутых выше файла, содержащих "скелет" будущего приложения - ui.R и server.R. Уже сейчас это приложение может быть запущено из консоли при помощи следующей команды (пакет Shiny должен быть перед этим активирован командой library(shiny)):
В результате выполнения этой команды откроется окно браузера (на моей машине это по умолчанию Google Chrome) с запущенным приложением:
Как видим, приложение запускается на локальном сервере по адресу localhost:8100. На данном этапе в браузере не отображается ничего, кроме названия приложения и залитой серым цветом области, зарезервированной для элементов графического интерфейса. Начнем добавлять эти элементы.
Таблица с данными, которые будут использованы для построения графиков, содержит переменные:
Сначала добавим в боковую панель приложения выпадающее меню, позволяющее пользователю выбрать озеро, для которого необходимо построить график. Для создания такого меню служит функция selectInput(). Заменим код в файле ui.R на следующий:
Сохранив изменения и запустив приложение, увидим боковую панель с только что созданным выпадающим меню:
Далее нам необходимо внести определенные изменения в файл, определяющий работу сервера. В частности, нужно описать, как на приложение будут подаваться входные данные и как будут выполняться и выводится на экран результаты вычислений. Приведенный ниже код для файла server.R демонстрирует несколько важных концепций, реализованных в пакете Shiny:
Таким образом, интерактивность приложения возникает благодаря использованию функций reactiveText() и reactivePlot(), которые отслеживают текущий выбор пользователя и производят обновление соответствующих переменных при изменении выбора.
В приведенном скрипте server.R мы создали две новые переменные в объекте output, а именно output$caption (заголовок графика) и output$lakePlot (собственно сам график). Чтобы эти новые объекты отображались в графическом интерфейсе приложения, необходимо внести соответствующие изменения в скрипте ui.R. В частности, заголовок графика вызывается функцией textOutput() и форматируется как h3-заголовок. График прорисовывается в основной панели (mainPanel) при помощи функции plotOutput():
Теперь наше приложение готово. Запустив его (команда runApp("D:/dreissena_app")), мы увидим страницу браузера с выпадающим меню слева и графиком для выбранного пользователем озера справа:
Созданным и хорошо отлаженным приложеним можно поделится с другими пользователями тремя разными способами:
Пакет Shiny позволяет создавать гораздо более гораздо более сложные приложения, чем рассмотренное в этом сообщении. Подробности - на сайте проекта (англ. яз.).
В настоящее время пакет Shiny не опубликован на сайте CRAN и поэтому для его инсталляции рекомендуется выполнить следующие команды (предполагается, что во время инсталляции Ваш компьютер подключен к Internet):
options(repos = c(RStudio = "http://rstudio.org/_packages", getOption("repos"))) install.packages("shiny")
В простейшем виде приложение, созданное при помощи Shiny, состоит из двух файлов, которые хранятся в одной папке. Один из этих обязательных файлов (должен иметь имя ui.R) содержит определения элементов пользовательского интерфейса; второй обязательный файл - server.R - содержит скрипт, определяющий работу сервера.
"Скелет" файла ui.R выглядит следующим образом:
library(shiny) # Функция shinyUI() задает структуру пользовательского интерфейса: shinyUI(pageWithSidebar( # Название приложения headerPanel("My application"), # Функция, определяющая структуру боковой панели приложения: sidebarPanel(), # Функция, определяющая структуру основного окна приложения: mainPanel() ))
"Скелет" файла, контролирующего работу сервера (server.R), выглядит так:
В качестве примера я приведу код приложения, которое будет строить диаграмму размахов по данным о длине раковины моллюска Dreissena polymorpha в трех озерах Беларуси, обследованных в мае, июле и сентябре 2003 г. (Mastitsky 2012; файл с данными, полученными в ходе этого исследования, хранится на сайте figshare). У пользователя будет возможность выбирать озеро, для которого он/она желает отобразить сезонную динамику размеров раковины моллюска. (Примечание: интерфейс приложения будет выполнен на английском языке. Я пока не проверял, "дружит" ли Shiny с кириллицей, но в принципе проблем быть не должно).
У себя на компьютере я создал папку с названием dreissena_app (по адресу D:\dreissena_app) и поместил в нее два упомянутых выше файла, содержащих "скелет" будущего приложения - ui.R и server.R. Уже сейчас это приложение может быть запущено из консоли при помощи следующей команды (пакет Shiny должен быть перед этим активирован командой library(shiny)):
runApp("D:/dreissena_app")
В результате выполнения этой команды откроется окно браузера (на моей машине это по умолчанию Google Chrome) с запущенным приложением:
Таблица с данными, которые будут использованы для построения графиков, содержит переменные:
- Lake: фактор с тремя уровнями, соответствующими названиям исследованных озер (Batorino, Naroch и Myastro).
- Month: фактор с тремя уровнями, соответствующими датам отбора проб дрейссены (May, July, September).
- Site: фактор с 9-ю уровнями, обозначающими станции, на которых проводился отбор проб (три станции в каждом озере). В рассматриваемом примере эта переменная никак не используется.
- ZMlength: измеренная длина раковины дрейссены (в мм). Всего было измерено 5068 моллюсков.
dat = read.delim("https://ndownloader.figshare.com/files/97988") summary(dat) Lake Month Site ZMlength Batorino:1219 July :1777 S5 : 733 Min. : 2.00 Myastro :1973 May :1662 S6 : 645 1st Qu.:12.00 Naroch :1876 September:1629 S7 : 645 Median :16.00 S8 : 627 Mean :15.85 S9 : 604 3rd Qu.:20.00 S4 : 595 Max. :35.00 (Other):1219
Сначала добавим в боковую панель приложения выпадающее меню, позволяющее пользователю выбрать озеро, для которого необходимо построить график. Для создания такого меню служит функция selectInput(). Заменим код в файле ui.R на следующий:
Сохранив изменения и запустив приложение, увидим боковую панель с только что созданным выпадающим меню:
Далее нам необходимо внести определенные изменения в файл, определяющий работу сервера. В частности, нужно описать, как на приложение будут подаваться входные данные и как будут выполняться и выводится на экран результаты вычислений. Приведенный ниже код для файла server.R демонстрирует несколько важных концепций, реализованных в пакете Shiny:
- Входные данные хранятся в объекте input, выходные - в объекте output. Извлечение необходимых данных выполняется обычным для R способом - при помощи оператора $ (подробнее о работе с таблицами данных см. здесь).
- Объект с данными, над которыми выполняются вычисления, инициализируется в момент запуска приложения.
- Для обновления выводимой на экран информации в реальном времени используются т.н. "реактивные" функции (т.е., функции, мгновенно реагирующие на выполненные пользователем изменения тех или иных параметров).
library(shiny) # Загрузка данных из внешнего источника: dat = read.delim("https://ndownloader.figshare.com/files/97988") shinyServer(function(input, output) { # Реактивная функция, которая будет возвращать значение, # соответствующее выбранному пользователем названию озера: lake = reactive(function(){ input$lake_to_plot } ) # Заголовок графика (хранится в слоте caption объекта output); # обновляется в зависимости от выбора, сделанного # пользователем в выпадающем меню боковой панели приложения: output$caption = reactiveText(function(){ title = lake() # актуальный в текущий момент выбор пользователя if(title == "Batorino") title = "Changes in lake Batorino" else {title = ifelse(title == "Myastro", "Changes in lake Myastro", "Changes in lake Naroch") } } ) # Построение диаграммы размахов: output$lakePlot = reactivePlot(function(){ LAKE = lake() boxplot(ZMlength ~ Month, data = dat[dat$Lake == LAKE, ], main = "", xlab = "Month", ylab = "Shell length (mm)") } ) })
Таким образом, интерактивность приложения возникает благодаря использованию функций reactiveText() и reactivePlot(), которые отслеживают текущий выбор пользователя и производят обновление соответствующих переменных при изменении выбора.
В приведенном скрипте server.R мы создали две новые переменные в объекте output, а именно output$caption (заголовок графика) и output$lakePlot (собственно сам график). Чтобы эти новые объекты отображались в графическом интерфейсе приложения, необходимо внести соответствующие изменения в скрипте ui.R. В частности, заголовок графика вызывается функцией textOutput() и форматируется как h3-заголовок. График прорисовывается в основной панели (mainPanel) при помощи функции plotOutput():
library(shiny) shinyUI(pageWithSidebar( # Название приложения: headerPanel("Dreissena shell length"), # Боковая панель с выпадающим меню: sidebarPanel( selectInput("lake_to_plot", "Select lake:", list("Batorino" = "Batorino", "Myastro" = "Myastro", "Naroch" = "Naroch")) ), mainPanel( h3(textOutput("caption")), plotOutput("lakePlot", height = "500px", width = "500px") ) ))
Теперь наше приложение готово. Запустив его (команда runApp("D:/dreissena_app")), мы увидим страницу браузера с выпадающим меню слева и графиком для выбранного пользователем озера справа:
Созданным и хорошо отлаженным приложеним можно поделится с другими пользователями тремя разными способами:
- Публикация кода на Gist. Оба обязательных файла (ui.R и server.R) должны быть частью опубликованного сниппета, как, например, здесь: https://gist.github.com/3239667. Для запуска приложения человек, с которым Вы им делитесь, должен иметь на своем компьютере установленные R и Shiny. Пользователю достаточно выполнить команду shiny::runGist("3239667"), где "3239667" - Gist-идентификатор сниппета. При вызове этой команды можно также указать прямую ссылку на сниппет: shiny::runGist("https://gist.github.com/3239667")
- Директорию с файлами приложения можно заархивировать и просто послать человеку, с которым Вы им хотите поделиться. После распаковывания архива, приложение запускается как обычно, т.е. при помощи команды runApp() (см. выше). Архив с рассмотренным в этом сообщении приложением Вы может скачать здесь.
- Наконец, приложение можно конвертировать в отдельный R-пакет.
Пакет Shiny позволяет создавать гораздо более гораздо более сложные приложения, чем рассмотренное в этом сообщении. Подробности - на сайте проекта (англ. яз.).
Listening on http://127.0.0.1:4511
Предупреждение в file(file, "rt") :
cannot open URL 'https://figshare.com/media/download/98923/97988': HTTP status was '404 Not Found'
Предупреждение: Error in file: cannot open the connection to 'http://figshare.com/media/download/98923/97988'
54: file
53: read.table
52: read.delim
Error in file(file, "rt") :
cannot open the connection to 'http://figshare.com/media/download/98923/97988'
Ссылочка подохла ((((
Отправить комментарий