Как я могу сделать данные, загруженные в блестящее приложение, пригодными для использования, а затем использовать их?
Я пытаюсь создать блестящее приложение, и я никогда не делал этого раньше.
Я хочу разрешить пользователю загружать данные из файла CSV по выбору пользователя, который выглядит примерно так:
ID Date Name Amount
123 01/12/2018 John Doe 100
124 01/02/2018 Bob Smith 110
125 01/03/2018 Jane Jones 100
126 01/02/2018 John Doe 110
127 01/03/2018 Bob Smith 100
128 01/04/2018 Jane Jones 110
129 01/03/2018 John Doe 100
130 01/04/2018 Bob Smith 110
131 01/04/2018 Jane Jones 120
132 01/14/2018 Tom Thomas 100
Затем я хочу, чтобы приложение использовало эти данные для запуска кода, такого как этот:
as.Date(myDF$Date, format="%m/%d/%Y")
sortedByDate = myDF[order(myDF$Date)]
amountPerDate = aggregate(data=myDF, Amount ~ Date, sum)
amountPerDate
произвести вывод, такой как этот:
Date Amount
01/02/2018 220
01/03/2018 300
01/04/2018 340
01/12/2018 100
01/14/2018 100
Таким образом, пользователь может видеть общую сумму за дату, с датами в правильном порядке. Я занимался такими вещами в обычном R-сценарии в течение нескольких месяцев, но никогда прежде не пробовал это блестяще.
Таким образом, чтобы загрузить данные в блестящий, я использую этот код:
shinyServer(function(input, output){
output$contents <- renderTable({
inFile <- input$file1
if(is.null(inFile))
return(NULL)
userData = read.csv(inFile$datapath, sep=",")
#here I run chunks of code to clean the data
#assign data frame to global environment
assign("userData", userData, envir = .GlobalEnv)
#display data table in app
userData
})
Так что теперь пользователь может просматривать данные, но не может ничего с ними сделать.
Во фрейме данных в глобальной среде каждая переменная имеет класс Factor. Я думал, что было бы легко привести переменные в их соответствующие классы (Числовые для "ID" и "Сумма", Символ для "Имя" и Дата для "Дата", но я не могу этого сделать. Самая следующая вещь, которую я пытаюсь чтобы сделать приложение, это отобразить дату в первой строке. Я попробовал это с этим кодом:
output$text <- renderText({
userData$Date = as.Date(as.character(userData$Date), format = "%m/%d/%Y")
userData[1,2]
})
Но вывод в приложении 17533, а не 01/12/2018, как я ожидал.
По какой-то странной причине следующий код выдаст результат от 01.12.2008:
output$text <- renderText({
userData$Date = as.character(userData$Date)
userData[1,2]
})
но мне нужно, чтобы даты были классом DATE, а не символом класса.
Без возможности привести переменные в соответствующие классы все мое приложение бесполезно. Пожалуйста помоги.
1 ответ
Не используйте assign в Shiny, это плохая практика, и она также не учитывает никакой реактивности. Вместо этого используйте реактив для хранения ваших входных данных.
Что касается неожиданного вывода на печать, это, вероятно, связано с тем, как хранятся даты. Если вы выводите объект Date в renderText, он, очевидно, проанализирует его как целочисленное значение и преобразует его в символ. Чтобы предотвратить это, сначала разберитесь с характером.
Вот рабочий пример:
library(shiny)
library(data.table)
server <- function(input, output, session) {
filedata <- reactive({
infile <- input$file1
if (is.null(infile)) {
return(NULL)
}
df <- fread(infile$datapath)
return(df)
})
output$my_table <- renderDataTable({
if(is.null(filedata()))
{
return(NULL)
}
else
{
myDF <- filedata() # read the uploaded data from reactive
myDF$Date <- as.Date(myDF$Date, format="%m/%d/%Y") # Change format!
sortedByDate = myDF[order(myDF$Date)]
amountPerDate = aggregate(data=myDF, Amount ~ Date, sum)
print('done')
return(amountPerDate)
}
})
output$my_text <- renderText({
if(is.null(filedata()))
{
return(NULL)
}
else
{
as.character(as.Date(filedata()$Date, format="%m/%d/%Y"))[1]
}
})
}
ui <- fluidPage(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
dataTableOutput('my_table'),
textOutput('my_text')
)
shinyApp(ui,server)
Надеюсь это поможет!