Я создаю блестящее приложение, в котором каждые 30 секунд reactivefilereader
считывает новые данные и обрабатывает их, добавляя к данным, накопленным с момента запуска приложения (функция обработки данных добавляет новые данные к существующим агрегированным данным и возвращает одно один ряд), а затем ggplot
нанесет это единственное наблюдение на график. И он будет непрерывно строить наблюдения с линией. Однако я получил это сообщение об ошибке, и в блестящем приложении ничего не отображается.
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
Мои данные таковы:
ts
Px
2020-03-13 17:15:19.000 23335.5
У меня есть глобальная переменная вне функции server
. Обратите внимание, что ниже не содержится никаких данных, потому что блестящий будет считывать данные каждые 30 секунд.
ggprice <- ggplot() + scale_colour_manual(values=c(Px="black"))
И график обновляется ниже и ts
- это данные. И он будет содержать только одно наблюдение.
ggprice <<- ggprice + geom_line(aes(x=Index,y=Px,colour = "Px"),data=ts)
Как мне преодолеть это?
Обновление: воспроизводимый пример по запросу.
У меня есть 2 глобальные переменные ниже, которые я знаю супер неуклюжий.
- Глобальная переменная 1 -
xts_bars_Agg
используется для хранения всех обработанных данных с момента запуска приложения - Глобальная переменная 2 -
ggprice
. Каждое новое наблюдение добавляется к этой глобальной переменной с помощью geom_line(...)
.
Как это можно оптимизировать? Можно ли здесь избежать глобальных переменных?
# Global variables
xts_bars_Agg <- NULL
# --- Function: Data I/O ------------------------------------------------------
data_processing <- function(csv_file){
df <- read.csv(csv_file, header=T,stringsAsFactors = F,colClasses = c("character","double"))
# convert String to timestamp, remove string timestamp
df <- (data.frame( Timestamp = strptime(df[,1],"%Y-%m-%d %H:%M:%OS"), df[,c(-1)]))
df_xts <- xts(x=df[,c(-1)], order.by=df$Timestamp)
xts_bars_Agg <<- rbind.xts(xts_bars_Agg,df_xts)
# *** the reason I need to rbind the new df_xts to
# existing xts_bars_agg (xts object)
# because the computeMagicalVal function below needs
# both the previous aggregated xts data plus the current xts data
# to compute a value.
# This and the usage of global variable looks very clumsy and inefficient and stupid to me.
# Is there a way to optimise this ?
df_xts_final <- computeMagicalVal(xts_bars_Agg)
# return df_xts_final with only one row,
# whereas xts_bars_Agg contains all the xts data with many rows
return(df_xts_final)
}
# second global variable
# global variable
ggprice <- ggplot() +
scale_colour_manual(values=c(Price="black"))
ggplot_func <- function(ts){
ggprice <<- ggprice + geom_line(aes(x=Index,y=Px,colour = "Price"),data=ts)
return(ggprice)
}
# UI
ui <- fluidPage(
#ggplot
mainPanel(
plotOutput(outputId = 'ggp')
)
)
# Define server logic
server <- function(input, output, session) {
df_update <- reactiveFileReader(intervalMillis = 10000,session=NULL,
filePath = "output.csv",
readFunc = data_processing)
output$ggp <- renderPlot({
ggplot_func(df_update())
})
}
# Run the application
shinyApp(ui = ui, server = server)