尝试从单个反应函数显示ggplot和dataframe

时间:2016-07-20 20:28:10

标签: r dataframe ggplot2 shiny

我可以使用下面的代码显示ggplot折线图或数据框,但不能同时显示两者。我知道反应函数应该创建一组ggplot或数据框可以使用的代码,但是我很难想出一个设置代码的好方法,这样两者都可以使用它,或者找到一种方法来分别读取线图的f2和表格的财务。

(来自server.r)

library(shiny)
library(ggplot2)

# Define server logic for slider examples
shinyServer(function(input, output) {

# Build wide Financials table
Financials <- data.frame(matrix(NA, ncol = 5, nrow = 4))
names(Financials) <- c(2016, 2017, 2018, 2019, 2020)
row.names(Financials) <- c("Cash", "Revenue", "EBITDA", "Liabilities")

# Build long Financials table
f2 <- data.frame(Amount=integer(1), Type=character(1), Year=character(1), stringsAsFactors = FALSE)


# Reactive expression to compose a data frame containing all of
# the values
mydata <- reactive({


# Find Column Number
colnum <- ifelse(input$k == -50, 2,
          ifelse(input$k == -40, 3,
          ifelse(input$k == -30, 4,
          ifelse(input$k == -20, 5,
          ifelse(input$k == -10, 6,
          ifelse(input$k == 0, 7,
          ifelse(input$k == 10, 8,
          ifelse(input$k == 20, 9,
          ifelse(input$k == 30, 10,
          ifelse(input$k == 40, 11,12))))))))))

# Find Row Number
rownum <- ifelse(input$perDay == 2.25, 2,
          ifelse(input$perDay == 2.5, 3,
          ifelse(input$perDay == 2.75, 4,
          ifelse(input$perDay == 3, 5,
          ifelse(input$perDay == 3.25, 6,
          ifelse(input$perDay == 3.5, 7,
          ifelse(input$perDay == 3.75, 8,
          ifelse(input$perDay == 4, 9,
          ifelse(input$perDay == 4.25, 10,
          ifelse(input$perDay == 4.5, 11,
          ifelse(input$perDay == 4.75, 12,
          ifelse(input$perDay == 5, 13, 14))))))))))))

for (i in 1:4) {
  # Set which sheet you're dealing with

  ifelse(i ==1, sheet <- "EC",
  ifelse(i == 2, sheet <- "Rev",
  ifelse(i == 3, sheet <- "EBITDA", sheet <- "Lia")))

  # For loop to start handling sheets and pulling values
  for (j in 1:5) {
    year <- 2015+j
    # assign the sheet to the variable
    file <- read.csv(paste(year, " ", sheet, ".csv", sep = ""), header = FALSE)
    # create variable to store the value, ex: EC2016
    value <- paste(sheet, year, sep = "")
    # assign the value to that variable
    value <- as.character(file[rownum,colnum])
    # convert value to an integer for the long table
    value3 <- as.integer(value)
    # make value into currency format for the table display
    value2 <- paste("$ ",format(as.double(value), big.mark=","),sep="")
    # write the value to the financials dataframe
    Financials[i, j] <- value2
    # create a new row for the long financial table
    newrow <- c(value3, sheet, year)
    names(newrow) <- c("Amount","Type","Year")
    # add newrow to the long financial table
    f2 <- rbind(f2, newrow)
  }
}
f2 <- f2[-1,]
f2 <- transform(f2, Amount = as.integer(Amount))

data.frame(Financials, check.names = FALSE)  

ggplot(data = f2, aes(x=Year, y=Amount, group=Type, colour=Type)) + geom_line() + geom_point() + scale_y_continuous(breaks =
    c(-12500000,-10000000,-7500000,-5000000,-2500000,0,
      2500000,5000000,7500000,10000000,12500000,15000000,17500000),
    labels = c("$-12,500,000", "$-10,000,000", "$-7,500,000","$-5,000,000","$-2,500,000","$0",
           "$2,500,000","$5,000,000","$7,500,000","$10,000,000","$12,500,000","$15,000,000","$17,500,000"))



}) 

output$chart <- renderPlot({
# Compose line graph
mydata()

})


# Show the values using an HTML table
output$values <- renderTable({
# Compose data frame
mydata()

  })
  })

2 个答案:

答案 0 :(得分:0)

将绘图部分移动到另一个函数中,然后可以调用mydata(),但返回数据上的绘图。您是否有特定原因要调用相同的函数来执行两种截然不同的任务?

答案 1 :(得分:0)

我们可以返回一个列表,例如:

return(list(mydata = data.frame(...), myplot = ggplot(...))

然后在renderPlot({mydata()$myplot})renderTable({mydata()$mydata})

这是一个有效的例子:

library(shiny)
library(ggplot2)

runApp(
  shinyApp(
    ui = {
      fluidPage(
        sidebarPanel(
          selectInput("mpg", "test", choices = seq(20, 35, 5), selected = 20)),
        mainPanel(
          tableOutput("myData"),
          plotOutput("myPlot")))
    },
    server = function(input, output, session){
      mydata <- reactive({
        mylist <- list(
          myData = mtcars[ mtcars$mpg <= input$mpg, ],
          myPlot = ggplot(mtcars[ mtcars$mpg <= input$mpg, ], aes(mpg, cyl)) +
            geom_point() +
            ggtitle(input$mpg)
        )
        return(mylist)
      })
      output$myData <- renderTable({mydata()$myData})
      output$myPlot <- renderPlot({mydata()$myPlot})
    }
  )
)