如何在 R 中反应性地做多个情节?

Posted

技术标签:

【中文标题】如何在 R 中反应性地做多个情节?【英文标题】:How to do multiple plots reactively in R? 【发布时间】:2019-10-05 00:41:05 【问题描述】:

R 中的响应式新手。尝试响应式文件读取 csv,然后根据给定的输入范围生成 3 个图以进行过滤。

我尝试将其添加为反应式,再次为每个 ggplot 调用 reactivefilereader data()。我很困惑如何对这些代码行进行分层,以便它可以是读取的响应文件,获取输入范围和过滤器,然后将其反馈给每个代码的渲染图/ggplot。我可以很好地获得 1 个情节,但尝试完成所有 3 个情节我只能得到最后一个情节。然后,如果我更改内容,我通常会遇到递归或反应性错误,或者我设法获得所有 3 个图,但在日期输入更改方面失去反应性。

这是我拥有的对日期更改做出反应的代码,但只能绘制最后一个图。

csv 文件如下所示:

    temp_h       humidity      pressure        pitch         roll           yaw          mag_x          mag_y          mag_z        accel_x       accel_y        accel_z     gyro_x   gyro_y   gyro_z     timestamp     
 ------------- ------------- ------------- ------------- ------------- ------------- -------------- -------------- ------------- ------------- -------------- ------------- -------- -------- -------- ---------------- 
  36.93448639   33.67306137             0   2.052537159   344.9172962   189.5288875   -24.15678406   -2.991427183   26.07371902   0.000484892   -0.262453765   0.948711813   ['x']    ['y']    ['z']    5/9/2019 11:57  
  37.00978851   34.73247528   1002.021484   359.9863889    343.752597    190.284607    -66.8992157    -8.57483387   71.15454865             0   -0.281751841   0.966257989   ['x']    ['y']    ['z']    5/9/2019 11:58  

.app 文件

#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library(shiny)
library(tools)
library(lubridate)
library(ggplot2)
library(dplyr)
theme_set(theme_bw())

ui <- fluidPage(
    titlePanel("Growth Chamber 109"),


    column(4, wellPanel(
        dateRangeInput(
            'dateRange',
            label = 'Filter results by date',
            start = as.Date('2019-01-01') ,
            end = NULL
                     )
    )),


    plotOutput("temp"),
    tags$head(
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.16/iframeResizer.contentWindow.min.js",
                    type = "text/javascript")
    ),
    html('<div data-iframe-height></div>')





)


#The reactive file reader reads in the Raspberry Pi Python generated file SenseLog.csv and returns as data()
server <- function(input, output, session) 
    data <- reactiveFileReader(
        intervalMillis = 5000,
        session = session,
        filePath = "SenseLog.csv",
        readFunc = read.csv)


    #Server call for rendering the plot output
    output$temp <- renderPlot(
        plot(data())


        #Change the function output data() to gc109. Reactive expressions/functions and the () mess me up sometimes
        gc109 <- data()



        #Parse time out  in proper format
        gc109$timestamp <-
            strptime(gc109$timestamp, "%Y-%m-%d %H:%M")


        #Filter data from logger based on date range input from session
        try1 <- subset(gc109, timestamp >= input$dateRange[1])
        try2 <- subset(try1, timestamp <= input$dateRange[2])


        #Fix column header names
        colnames(try2)[colnames(try1) == "timestamp"] <- "Date"
        colnames(try2)[colnames(try1) == "temp_h"] <- "Temperature"
        colnames(try2)[colnames(try1) == "humidity"] <- "Humidity"
        colnames(try2)[colnames(try1) == "pressure"] <- "Pressure"


        #Fix dates/maintain time to plot properly
        try2$Date <- as.POSIXct(try2$Date)


        #Generate temperature plot

        ggplot(aes(x = Date, y = Temperature), data = try2) + geom_point() +
            theme(text = element_text(size = 20))
        ggplot(aes(x = Date, y = Humidity), data = try2) + geom_point() +
            theme(text = element_text(size = 20))
        ggplot(aes(x = Date, y = Pressure), data = try2) + geom_point() +
            theme(text = element_text(size = 20))
        )




shinyApp(ui, server)

【问题讨论】:

要么返回 3 个不同的反应绘图对象,要么将 3 个绘图合二为一(可能使用 cowplot 包)然后返回 1 个绘图。目前,您的output$temp &lt;- renderPlot(... 只会返回最后一个情节。 关于性能,您可能想看看闪亮的plot caching 功能。 【参考方案1】:

谢谢,但我确实希望找到一种更优雅的方式——我只是担心效率,希望我知道如何从 1 个数据处理事件中调用 3 个图。这就是我的解决方案,似乎已经足够了。

#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library(shiny)
library(tools)
library(lubridate)
library(ggplot2)
library(dplyr)
theme_set(theme_bw())

ui <- fluidPage(
    titlePanel("Growth Chamber 109"),


    column(4, wellPanel(
        dateRangeInput(
            'dateRange',
            label = 'Filter results by date',
            start = as.Date('2019-05-10') ,
            end = NULL
        )
    )),


    plotOutput("Temperature"),
    tags$head(
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.16/iframeResizer.contentWindow.min.js",
                    type = "text/javascript")
    ),
    HTML('<div data-iframe-height></div>'),

    plotOutput("Humidity"),
    tags$head(
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.16/iframeResizer.contentWindow.min.js",
                    type = "text/javascript")
    ),
    HTML('<div data-iframe-height></div>'),

    plotOutput("Pressure"),
    tags$head(
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.16/iframeResizer.contentWindow.min.js",
                    type = "text/javascript")
    ),
    HTML('<div data-iframe-height></div>')





)


#The reactive file reader reads in the Raspberry Pi Python generated file SenseLog.csv and returns as data()
server <- function(input, output, session) 
    data <- reactiveFileReader(
        intervalMillis = 5000,
        session = session,
        filePath = "SenseLog.csv",
        readFunc = read.csv)


    #Server call for rendering the temperature plot
    output$Temperature <- renderPlot(


        #Change the function output data() to gc109. Reactive expressions/functions and the () mess me up sometimes
        gc109 <- data()



        #Parse time out  in proper format
        gc109$timestamp <- strptime(gc109$timestamp, "%Y-%m-%d %H:%M")


        #Filter data from logger based on date range input from session
        try1 <- subset(gc109, timestamp >= input$dateRange[1])
        try2 <- subset(try1, timestamp <= input$dateRange[2])


        #Fix column header names
        colnames(try2)[colnames(try1) == "timestamp"] <- "Date"
        colnames(try2)[colnames(try1) == "temp_h"] <- "Temperature"
        colnames(try2)[colnames(try1) == "humidity"] <- "Humidity"
        colnames(try2)[colnames(try1) == "pressure"] <- "Pressure"


        #Fix dates/maintain time to plot properly
        try2$Date <- as.POSIXct(try2$Date)


        #Generate temperature plot

        ggplot(aes(x = Date, y = Temperature), data = try2) + geom_point() +
            theme(text = element_text(size = 20))

    )



    data <- reactiveFileReader(
        intervalMillis = 5000,
        session = session,
        filePath = "SenseLog.csv",
        readFunc = read.csv)


    #Server call for rendering the humidity plot
    output$Humidity <- renderPlot(


        #Change the function output data() to gc109. Reactive expressions/functions and the () mess me up sometimes
        gc109 <- data()



        #Parse time out  in proper format
        gc109$timestamp <- strptime(gc109$timestamp, "%Y-%m-%d %H:%M")


        #Filter data from logger based on date range input from session
        try1 <- subset(gc109, timestamp >= input$dateRange[1])
        try2 <- subset(try1, timestamp <= input$dateRange[2])


        #Fix column header names
        colnames(try2)[colnames(try1) == "timestamp"] <- "Date"
        colnames(try2)[colnames(try1) == "temp_h"] <- "Temperature"
        colnames(try2)[colnames(try1) == "humidity"] <- "Humidity"
        colnames(try2)[colnames(try1) == "pressure"] <- "Pressure"


        #Fix dates/maintain time to plot properly
        try2$Date <- as.POSIXct(try2$Date)


        #Generate temperature plot

        ggplot(aes(x = Date, y = Humidity), data = try2) + geom_point() +
            theme(text = element_text(size = 20))

    )

    data <- reactiveFileReader(
        intervalMillis = 5000,
        session = session,
        filePath = "SenseLog.csv",
        readFunc = read.csv)


    #Server call for rendering the pressure plot
    output$Pressure <- renderPlot(


        #Change the function output data() to gc109. Reactive expressions/functions and the () mess me up sometimes
        gc109 <- data()



        #Parse time out  in proper format
        gc109$timestamp <- strptime(gc109$timestamp, "%Y-%m-%d %H:%M")


        #Filter data from logger based on date range input from session
        try1 <- subset(gc109, timestamp >= input$dateRange[1])
        try2 <- subset(try1, timestamp <= input$dateRange[2])


        #Fix column header names
        colnames(try2)[colnames(try1) == "timestamp"] <- "Date"
        colnames(try2)[colnames(try1) == "temp_h"] <- "Temperature"
        colnames(try2)[colnames(try1) == "humidity"] <- "Humidity"
        colnames(try2)[colnames(try1) == "pressure"] <- "Pressure"


        #Fix dates/maintain time to plot properly
        try2$Date <- as.POSIXct(try2$Date)


        #Generate temperature plot

        ggplot(aes(x = Date, y = Pressure), data = try2) + geom_point() +
            theme(text = element_text(size = 20))

    )



shinyApp(ui, server)

【讨论】:

希望有更有效的解决方案。前两个情节也以一种奇怪的方式重叠。同样关于使用树莓派通过 rsconnect 推送,错误代码 1 但很可能是路径问题。

以上是关于如何在 R 中反应性地做多个情节?的主要内容,如果未能解决你的问题,请参考以下文章

如果使用情节提要布局,如何在 R flexdashboard 页面上显示多个绘图

在 Vue.js 中反应性地重新填充指令数组

R Shiny:如何使多个元素在添加/删除按钮上下文中具有反应性?

从Redis FIFO队列中弹性地弹出多个值

闪亮的反应情节失败

如何在框内添加文本,并在 R 闪亮中绘制情节?