【发布时间】:2020-11-13 07:29:23
【问题描述】:
目标
实施一个闪亮的应用程序,以有效地可视化和调整上传的数据集。每组可能包含 100000 到 200000 行。数据调整完成后,即可下载调整后的数据。分步:
- 数据上传
- 数据选择和可视化
- 数据(点)移除
- 下载选项
问题
虽然该应用程序正常工作,但数据可视化和删除需要太多时间。
代码
样本数据
生成了一些示例数据。数据可以上传到闪亮的应用程序。样本数据分布与我的实际数据不相似。实际数据包含清晰可辨的异常值,看起来像带有峰的光谱。
a = sample(1:1e12, 1e5, replace=TRUE)
b = sample(1:1e12, 1e5, replace=TRUE)
dummy1 = data.frame(Frequency = a, Amplitude = a)
dummy2 = data.frame(Frequency = b, Amplitude = b)
dummy3 = data.frame(Frequency = a, Amplitude = b)
# Sample data
write.csv(dummy1,'dummy1.csv')
write.csv(dummy2,'dummy2.csv')
write.csv(dummy3,'dummy2.csv')
闪亮的应用
应用程序获取上传的数据并绘制它。 (可以将样本虚拟数据上传到应用程序。)可以删除部分数据点并下载新数据。
# Packages
library(shiny)
library(ggplot2)
library(data.table)
# UI
ui = fluidPage(
fluidRow(selectInput("selection", "Set Selection:", choices = '', selected = '', multiple = TRUE)),
fluidRow(plotOutput(outputId = "plot", brush = "plot_brush_"),
downloadButton('download',"Download the data"))
)
# Server
server = function(session, input, output){
# Pop up for data upload
query_modal = modalDialog(title = "Upload Spectrum",
fileInput("file",
"file",
multiple = TRUE,
accept = c(".csv")),
easyClose = FALSE)
showModal(query_modal)
## Upload
mt1 = reactive({
req(input$file)
cs = list()
for(nr in 1:length(input$file[ , 1])){
c = read.csv(input$file[[nr, 'datapath']])
cs[[nr]] = data.table(Frequency = as.numeric(c[[1]]),
Amplitude = as.numeric(c[[2]]),
Indicator = as.factor(nr))}
c = do.call(rbind, cs)
c = reactiveValues(data = c)
return(c)})
## Input selection
observeEvent(
mt1(),
updateSelectInput(
session,
"selection",
"Set Selection:",
choices = levels(mt1()$data$Indicator),
selected = 'Entire'))
## Plot
output$plot <- renderPlot({
mt = mt1()$data
mt = mt[mt$Indicator %in% input$selection,]
p = ggplot(mt, aes(Frequency, Amplitude, color = Indicator))
p + geom_point(show.legend = TRUE)})
## Download
output$download = downloadHandler(
filename = function(){paste(gsub('.{1}$', '', input$file$name[1]), 'manipulated', '.csv', sep= '')},
content = function(fname){
mt = mt1()$data
mt = mt[, .SD, .SDcols= c('Frequency',
'Amplitude',
'Indicator')]
write.csv(mt, fname, row.names = FALSE)})
## Adjust
observe({
d = mt$data
keep = mt$data[!Indicator %in% input$selection]
df = brushedPoints(d, brush = input$plot_brush_, allRows = TRUE)
df = df[selected_ == FALSE]
df$selected_ = NULL
mt$data = rbind(keep , df[Indicator %in% input$selection, ])})
}
# Run app
shinyApp(ui = ui, server = server)
【问题讨论】:
-
所有与闪亮相关的代码都无关紧要。你有一个纯粹的绘图/ggplot2 问题。绘制许多点很慢。您需要重新设计图表并进行更有效的数据可视化。绘制 1e5 个点是不明智的。你会有戏剧性的过度情节。如果您不想进行更有效的可视化,我的这个答案可能很有用:stackoverflow.com/a/16668596/1412059
-
"我目前会更改数据本身" 如果 情节 仍然完全相同,那有什么问题?在一个情节中不可能区分 1e5 个点。此外,您应该查看其他选项(如 hexbin 图)。
-
@Roland,我同意这是一个阴谋问题。然而,数据点的绘图是必要的,因为绘图既可以作为可视化工具来了解要删除的数据点,也可以作为数据删除的数据操作工具。我喜欢你的近似方法。我必须了解数据大小和精度,这是没有问题的。我不明白为什么 R 的 ggplot 或基本图比 Python 的 matplotlib 花费更多的时间。我想,除了近似值之外,理想的做法是在具有近似值和缩减数据的绘图顶部的原始数据上运行相同的选择层功能。
-
@Roland,我确认 1e5 分对于 matplotlib 和 Matlab 来说都不是什么大问题,请参阅我的回答。
标签: r shiny large-data