0

I'm creating a shiny app with local persistent data referred from Dean Attali blog as in section: 1. Local file system (local).

My query is, is it possible to create value box output from this method?

aggregates data from inputs

formData <- reactive({
  formdata <- c("Associate Name" = input$aname,"Associate Email"=input$aemail,"Client Name" = input$cname,
            "Client Email"=input$cemail,"Ask By Customer"=input$ask,"Remarks"=input$rem ,
            "Date" = as.character(input$date), "Followup Date" = as.character(input$fdate))

  formdata <- t(formdata)
  formdata
})

saves data to csv (this creates a separate file every time we submit)

saveData <- function(formdata) {
   fileName <- sprintf("%s_%s.csv",
                       humanTime(),
                       digest::digest(formdata))

   write.csv(x = formdata, file = file.path(responsesDir, fileName),
             row.names = FALSE, quote = TRUE)
}

loads the data (Binding all csv's which contains responses)

Data <- reactive( {
  # Read all the files into a list
  files <- list.files(responsesDir, full.names = TRUE)
  data <- lapply(files, read.csv, stringsAsFactors = FALSE)
  # Concatenate all data together into one data.frame
  data <- do.call(rbind, data)
  data <- data.frame(data)
  data
}

displaying data in a table

output$responses <- DT::renderDataTable({
input$submit
Data()
})

I would like to know if we could create valueBoxOutput to display number of times an Associate name is recorded, number of times a client name has been recorded

E.g: someClient - 10, someAssociate - 5

This is my first shiny app, please help me through this. Thanks in advance!!

2 Answers2

1

Yes you can do this. First, you need to make the data you read in using loadData a reactive, not a function. Then refer to this reactive in output$responses instead of loadData.

Then, create another reactive, associateClientText say, that extracts the information you want to display in the box from the data reactive you created above.

Finally, refer to associateClientText in the definition of your value box.

Answering your question in the comments below: here is a simple self-contained example showing how to read multiple csv files and bind them into a single dataframe/tibble.

library(tidyverse)

# Create some dummy data and write to CSV files
data1 <- tibble(x=rnorm(5), y=rnorm(5))
data2 <- tibble(x=rnorm(5), y=rnorm(5))
write.csv(data1, "data1.csv", row.names=FALSE)
write.csv(data2, "data2.csv", row.names=FALSE)

# Read in test data and combine in a single tibble
allData <- bind_rows(lapply(c("data1.csv", "data2.csv"), function(fName) read.csv(fName) %>% add_column(sourceFile=fName)))
allData

Giving

            x           y sourceFile
1   0.1663704 -1.53566430  data1.csv
2   1.2903028  0.92808401  data1.csv
3  -0.7523470 -0.54466037  data1.csv
4   0.1036518  0.31038474  data1.csv
5   1.7568151  0.24742720  data1.csv
6  -1.3975505 -0.04481848  data2.csv
7  -0.2800692 -0.67718383  data2.csv
8  -0.8773866  0.18190370  data2.csv
9  -0.9915960 -3.16427113  data2.csv
10  0.6501058 -0.79753204  data2.csv

I can't give your more direct help because you haven't provided your own simple, self-contained example. This post may be helpful.

You can copy my bind_rows code into your reactive. Personally, I'd rename the reactive as loadData is no longer an accurate description of what it's doing: it's not loading the data, it is the data.

Limey
  • 10,234
  • 2
  • 12
  • 32
  • `column(width=4, div(id = "form", textInput("aname", "Associate Name",value = ""), textInput("aemail", "Associate Email",value = ""), textInput("cname", "Client Name",value = ""), textInput("cemail", "Client Email",value = ""), textInput("ask", "Ask by Customer",value = ""),)), column(width=1), column(width=4,div(id = "form1", textInput("rem", "Remarks",value = ""), radioButtons("bill","Billing",choices = c("Yes","No")), dateInput("date", "Date", min = "2000-01-01",format = "dd-mm-yyyy"), dateInput("fdate", "Followup Date", min = "2000-01-01",format = "dd-mm-yyyy"))),),)` – Harish Kumar Jun 04 '20 at 12:21
  • this is my UI that takes input and I have mentioned the functions that aggregates, save and loads and display the data in the question. It would be really kind to help me as I'm banging on it for a couple of days. I have also changed the reactive as Data() from LoadData() as per your suggestions – Harish Kumar Jun 04 '20 at 13:09
  • @Geovany would you be able to help me here please – Harish Kumar Jun 04 '20 at 13:46
0

I figured it how to do it. the trick is in how we using the reactive function.

 output$billing <- renderValueBox({
    valueBox(value = length(Data()$Billing[Data()$Billing =="Yes"]),
             subtitle = "No. of RFP's billed", color = "green",icon=icon("money",lib = "font-awesome"))

  })