Xây dựng ứng dụng web Taxi với Shiny

NYC yellow taxi
NYC yellow taxi

Trong bài viết này, ta sẽ cùng nhau xây dựng một web app tương tự như app này. Ta sẽ sử dụng tập dữ liệu taxi trong tháng 1/2015 được cung cấp bởi the NYC Taxi & Limousine Commission. Ta cần cài đặt RStudio để xây dựng ứng dụng này. Do tập dữ liệu rất lớn (khoảng vài trăm MB) nên ta sẽ tạo một mẫu dữ liệu nhỏ hơn để dễ dàng thao tác (download tập dữ liệu ở đây).

Tạo mẫu dữ liệu để thao tác

Ta sử dụng các dòng lệnh sau để rút trích mẫu dữ liệu

library(dplyr)
taxiData <- read.csv('yellow_tripData.csv', stringsAsFactors = FALSE)
taxiData <- sample_frac(taxiData, 0.01)
write.csv(taxiData, file = 'taxiData.csv')

Ta có thể tìm hiểu thêm về hàm sample_frac ở trang web dplyr tutorial.

Xây dựng ứng dụng với Shiny

Để xây dựng ứng dụng web với shiny, ta cần hai file sau:

  • ui.R
  • server.R

File ui.R được dùng để layout cho ứng dụng. File server.R được dùng để thực hiện các mã lệnh của ứng dụng.

Đầu tiên, ta tạo một folder chứa hai file ui.R, server.R, và copy tập dữ liệu tripData.csv vào. Ta thiết lập folder này là folder làm việc hiện hành (working directory).

Ta sẽ viết code cho ui.R. Đoạn code bên dưới gồm có ba panels:

  • Header Panel – nằm trên cùng, dùng hiển thị tiêu đề.
  • Sidebar Panel – nằm bên tay trái, dùng hiển thị các control inputs.
  • Main Panel – nằm bên tay phải, dùng hiển thị kết quả xử lý.
shinyUI(pageWithSidebar(
 headerPanel('NYC Yellow Taxi Trips in January 2015'),
 sidebarPanel(
 selectInput('day', 'Choose the day', choices = c('Sunday' = 1, 'Monday' = 2, 'Tuesday' = 3, 'Wednesday' = 4, 'Thursday' = 5, 'Friday' = 6, 'Saturday' = 7)),
 sliderInput('startHour', 'Choose the starting hour', min = 0, max = 23, value = 3),
 sliderInput('endHour', 'Choose the ending hour', min = 0, max = 23, value = 7)
 ),
 mainPanel(
 p('This shiny app will show you the number of yellow taxi trips that occurred on a particular day between the selected hours.'),
 h4('The day you chose:'),
 verbatimTextOutput('day'),
 h4('The starting hour you chose:'),
 verbatimTextOutput('startHour'),
 h4('The ending hour you chose:'),
 verbatimTextOutput('endHour'),
 h4('The number of yellow taxi trips in the selected time period'),
 plotOutput('taxiPlot')
 )
))

Đầu tiên, ta đặt tên tiêu đề. Sau đó, ta tạo ba input control nằm trong sidebar panel. Input đầu tiên là một dropdown menu gồm danh sách các lựa chọn, và hai input còn lại là các slider.

Tiếp đến, ta lập trình cho main panel, p và h4 là các thẻ HTML. p là paragraph, h4 là heading level 4. verbatimTextOutput và plotOutput dùng để hiển thị kết quả phân tích.

Trong file server.R, ta cần 3 thư viện, dplyr để biến đổi dữ liệu, lubridate để xử lý dữ liệu ngày tháng, và BH hỗ trợ Shiny publish ứng dụng lên web. Đầu tiên, ta nạp dữ liệu vào chương trình.

library(dplyr)
library(lubridate)
library(BH)
taxiData <- read.csv('tripData.csv', stringsAsFactors = FALSE)

Ta quan tâm đến cột dữ liệu tpep_pickup_datetime. Khi check kiểu dữ liệu của cột thuộc tính bằng hàm class(taxiData$tpep_pickup_datetime), ta có thể thấy nó thuộc lớp character. Đầu tiên, ta cần chuyển đổi sang kiểu dữ liệu ngày tháng trong R (POSIXct). Ta có thể dùng hàm ymd_hms trong thư viện lubridate.

taxiData$tpep_pickup_datetime <- ymd_hms(taxiData$tpep_pickup_datetime)

Tiếp theo, ta tạo một cột dữ liệu mới gọi là Day, chứa thông tin thứ trong tuần. Ta có thể truy xuất thông tin thứ trong tuần như sau:

taxiData$Day <- wday(taxiData$tpep_pickup_datetime)

Tiếp theo, ta viết hàm để xuất ra dạng biểu đồ.

tripsPlot <- function(day, startHour, endHour) {
 tripsData <- subset(taxiData, Day == day)
 tripsTable <- table(hour(tripsData$tpep_pickup_datetime))
 tripsTable <- as.table(tripsTable[(startHour + 1):(endHour + 1)])
 taxiPlot <- plot(tripsTable, type = 'o', xlab = 'Hour', xlim = c(startHour, endHour))
 return(taxiPlot)
}

Đầu tiên, ta sẽ lấy tập con của tập dữ liệu tripData, chỉ chứa những điểm dữ liệu tương ứng với thứ trong tuần được chọn. Sau đó, ta sẽ xây dựng một table. Table này sẽ trả về số lượng chuyến đi tương ứng với mỗi đơn vị giờ trong thứ đó. Ta quan sát tripsTable có dạng như sau:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1059 911 714 555 351 139 144 223 336 486 704 820 901 974 909 849 833 825 832 759 20 21 22 23 691 638 602 509

Điều này có nghĩa là có 1059 lượt đón taxi vào lúc giữa đêm cho đến 1 giờ sáng, 911 lượt đón taxi vào lúc 1 giờ sáng cho đến 2 giờ sáng, và cứ thế. Tiếp theo, ta sẽ lọc ra dữ liệu theo các khoảng thời gian tương ứng với sự lựa chọn của người dùng. Ta cần chuyển đổi sang kiểu dữ liệu table vì tripsTable[(startHour + 1):(endHour + 1)] sẽ trả về một array thay vì một table. Sau cùng, ta sẽ viết hàm biểu diễn dữ liệu.

Đoạn code sau cùng chứa nội dung chính mà shiny server thực hiện.

shinyServer(
 function(input, output) {
 output$day <- renderPrint({input$day})
 output$startHour <- renderPrint({input$startHour})
 output$endHour <- renderPrint({input$endHour})
 output$taxiPlot <- renderPlot({tripsPlot(input$day, input$startHour, input$endHour)})
 }
)

Ta chỉ định các biến nào được in ra màn hình. renderPrint được dùng để hiển thị text, renderPlot dùng để hiển thị biểu đồ. Khi hoàn tất, ta click vào nút Run App nằm ở góc trên cùng bên phải của RStudio. Khi click nút này, ta sẽ chạy được ứng dụng như hình bên dưới.

NYC
NYC

Nếu bạn muốn publish lên web, click vào nút Publish nằm ở góc trên cùng bên phải của màn hình window, sau đó làm theo hướng dẫn được yêu cầu.

Bạn có thể tham khảo đoạn code tại Github: https://github.com/ongxuanhong/shinyapps-taxi

Nguồn: http://www.r-bloggers.com/building-interactive-web-apps-with-shiny/

Advertisements

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s