I have an rshiny app and i'm trying to download a csv file from the app after it is edited. I followed the examples online, but the download button isn't working. I know the button is fine, its copied directly from the rshiny documentation. I assume the error is server side
server <-function(input,output){# Combine the selected variables into a new data frame
#output$value <- renderPrint({
# str(input$GimmeCSV[2,2])
output$table.preview <- renderTable({
inFile <- input$GimmeCSV
preview <- read.csv(inFile$datapath, header=TRUE, sep=",")
return(head(preview)) # undo Table can be modified
})
output$table.output <- renderTable({
inFile <- input$GimmeCSV
tbl <- read.csv(inFile$datapath, header=TRUE, sep=",")
#return(head(tbl)) # undo Table can be modified
################^ preview of csv table################
#look up how to extract the columns with no name present(something numerical)
#After that is figured out calculating the rest of those values will be a snap
#tbl <- read.csv(inFile$datapath, header=TRUE, sep=",")
#below is temporary file path only used for testing purposes, the above read.csv is the true pooba
#STANDARDS!!!
solar <- tbl$solar
temp <- tbl$temp
ws <- tbl$ws
#return(head(solar))
Ktemp <-temp + 273
ktemp <-temp + 273
#lol
if ((input$Shape) == shape_select[1]){
Len <- (input$diacone)
Height <- (input$hgtcone)
Width <- 0
} else {if((input$Shape) == shape_select[2]){
Len <- (input$diasphere)
Height <- 0
Width <- 0
}
else
Len <- (input$lenprism)
Height <- (input$hgtprism)
Width <- (input$widprism)
}
r <-Len/2
#return(r)
if (Len >=0.037){ # Absorptivity from Luke Miller
Abs <- 0.615
} else {if (Len <= 0.02225 ){Abs <-0.689
} else Abs <- 0.68 }
#works!
Emm <-0.97
#TOTALLY ARBITURARY SURFACE AREA VALUES BASED ON WHAT I KNOW!
ConeA <- (pi*r*r) + (sqrt((Height*Height)+(r*r))) # area of cone
SphereA <- (4*pi*(r*r)) #area of sphere
PrismA <- ((2*Len*Width) + (2*Height*Len) +( 2*Height*Width))
#return(PrismA)
#WORKS
#Deciding which surface area area to calculate
if ((input$Shape) == shape_select[1]){
SA <-ConeA
} else {if((input$Shape) == shape_select[2]){SA <- SphereA}
else SA <-PrismA}
#WOEKS!!!!!!!
#return(SA)
#Temporary placeholder values for PSA
PSA <- SA
SB <- 5.67E-08 # Stephan Boltzman constant
eskyclear <- 0.72 + (0.005*temp)
CC <- 0.5 #Cloud over 0 - 1
esky <- eskyclear + CC*(1 - eskyclear - (8/ktemp)) #IR emissivity from sky
Aradsky <- SA/2 #surface area projected to the sky
Aradground <- SA/2 # surface area projected to the ground
K3 <- esky^(1/4)
K2 <- 4 * SB * Emm * (esky)^(3/4)
K4 <- 4 * SB * Emm
K5 <- 0.6/(0.5*Len)
hc <- 0.6
com1 <- (Abs * solar) + (K2 * (Aradsky/PSA) * K3 * Ktemp^4) + (K4 * (Aradground/PSA) * Ktemp^4) + (K5 * PSA * Ktemp) + (hc*SA*Ktemp) + 2.48*0
com2 <- (4180 * 0) + ((Ktemp^3) * K2 * (Aradsky/PSA)) + (K4 * (Aradground/PSA) *(Ktemp^3)) + (hc*SA) + (K5*PSA)
#works!
Sol <- com1 / com2
modeltemp <- Sol - 273
max <- max(modeltemp)
min <- min(modeltemp)
mydata <- data.frame( Daily_Temp = temp, Solar_Radiation = solar, Body_Temperature = modeltemp, stringsAsFactors = FALSE)
return(mydata)
output$downloadData <- downloadHandler(
filename = function() { paste(input$inFile, '.csv', sep='') },
content = function(file) {
write.csv(mydata, file)
}
)
})
} #app goes here lol
shinyApp(ui, server)
}
Any sugestions are appreciated
I rearranged your code a bit and created 2 reactiveValues at the beginning of the server function.
In an observeEvent, you wait until the fileInput-Button (input$GimmeCSV) is clicked, it reads the csv then and assigns it to the reactive value inputFile. Then you can access this value directly in both renderTable outputs, as you would load the csv twice in your example. If the file is not too big, it shouldnt be a problem, but its not necessary.
The downloadHandler goes outside the renderTable function and takes the input argument (input$inFile), which is used to name the output file. For the content, the second reactiveValue is used, where the data was assigned in output$table.output.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("GimmeCSV", "Upload a CSV", multiple = F),
textInput("inFile", "Name for Output"),
downloadLink("downloadData", "Download")
),
mainPanel(
tableOutput("table.preview"),
tableOutput("table.output")
)
)
)
server <-function(input,output){
inputFile <- reactiveValues(file = NULL)
outputFile <- reactiveValues(file=NULL)
observeEvent(input$GimmeCSV, {
inFile <- input$GimmeCSV
data <- read.csv(inFile$datapath, header=TRUE, sep=";")
inputFile$file <- data
})
output$table.preview <- renderTable({
head(inputFile$file)
})
output$table.output <- renderTable({
tbl <- inputFile$file
outputFile$file <- tbl
tbl
})
output$downloadData <- downloadHandler(
filename = function() {
paste(input$inFile, '.csv', sep='')
},
content = function(file) {
write.csv(outputFile$file, file)
}
)
}
shinyApp(ui, server)
Hope it helps.
Related
I am trying to write my first Shiny App that reads a PDF file, extracts tables and saves it into Excel document.
I am failing to produce suitable code. So far I have:
1) For UI
shinyUI(fluidPage(
titlePanel("CMM Report"),
sidebarPanel(
fileInput("file", "Upload Report")
),
downloadButton("dl", "Download")
))
2) For Server
library(shiny)
library (tabulizer)
library(writexl)
shinyServer(function(input, output) {
data <- reactive({
file1 <- input$file
if(is.null(file1)){return()}
file1 <- ExtractTable (file1)
})
## Download
output$dl <- downloadHandler(
filename = function() { "ae.xlsx"},
content = function(file) {write_xlsx(data, path = file)}
)
})
I am not sure If I need to put the code for extracting table in a function and where to call the function, to make it work. Any help REALLY appreciated.
The data file of the example is from here
report <- "http://www.stat.ufl.edu/~athienit/Tables/Ztable.pdf"
Function to extract data
ExtractTable <- function (report){
lst <- extract_tables(report, encoding="UTF-8")
# Delete blank columns
lst[[1]] <- lst[[1]][, -3]
lst[[2]] <- lst[[2]][, -4]
# Bind the list elements
table <- do.call(rbind, lst)
table <- as.data.frame(table[c(2:37, 40:nrow(table)), ],
stringsAsFactors=FALSE) # ...w/o obsolete rows
# Take over colnames, cache rownames to vector
colnames(table) <- table[1, ]
rn <- table[2:71, 1]
table <- table[-1,-1] # and bounce them out of the table
# Coerce to numeric
table <- as.data.frame(apply(table[1:70,1:10], 2,
function(x) as.numeric(as.character(x))))
rownames(table) <- rn
return(table)
}
Could you try:
shinyServer(function(input, output) {
data <- reactive({
file1 <- input$file
if(is.null(file1)){return()}
ExtractTable(file1$datapath) # $datapath was missing
})
## Download
output$dl <- downloadHandler(
filename = function() { "ae.xlsx"},
content = function(file) {write_xlsx(data(), path = file)} # parentheses () were missing
)
})
Below is my code. It might seem a bit long but actually it's a VERY simple app.
The user is supposed to upload a tiny data frame (x.csv if you are in the US or x_Europe.csv if you are in Europe). Then the user should click on the button to start calculations. And then at the end the user should be able to download the results of those calculations as a data frame.
My problem: after I upload the file, when I click on the 'do_it' action button - nothing happens. I can see it because nothing is being printed to my console. WHY? After all, my function 'main_calc' should be eventReactive to input$do_it? Why do all the calculations inside main_calc start happening ONLY after the user tries to download the results?
Important: It is important to me to keep the 'Data' function separately from main_calc.
Thank you very much!
First, generate one of these 2 files in your working directory:
# generate file 'x.csv' to read in later in the app:
write.csv(data.frame(a = 1:4, b = 2:5), "x.csv", row.names = F) # US file
write.csv2(data.frame(a = 1:4, b = 2:5), "x_Europe.csv", row.names = F)
This is the code for the shiny app:
library(shiny)
ui <- fluidPage(
# User should upload file x here:
fileInput("file_x", label = h5("Upload file 'x.csv'!")),
br(),
actionButton("do_it", "Click Here First:"),
br(),
br(),
textInput("user_filename","Save your file as:", value = "My file x"),
downloadButton('file_down',"Save the output File:")
)
server <- function(input, output, session) {
#----------------------------------------------------------------------
# Function to read in either European (csv2) or American (csv) input:
#----------------------------------------------------------------------
ReadFile <- function(pathtofile, withheader = TRUE){
test <- readLines(pathtofile, n = 1)
if (length(strsplit(test, split = ";")[[1]]) > 1) {
print("Reading European CSV file")
outlist <- list(myinput = read.csv2(pathtofile, header = TRUE),
europe.file = 1)
} else {
print("Reading US CSV file")
outlist <- list(myinput = read.csv(pathtofile, header = TRUE),
europe.file = 0)
}
return(outlist)
}
#----------------------------------------------------------------------
# Data-related - getting the input file
#----------------------------------------------------------------------
Data <- reactive({
print("Starting reactive function 'Data'")
# Input file:
infile_x <- input$file_x
myx <- ReadFile(infile_x$datapath)$myinput
# European file?
europe <- ReadFile(infile_x$datapath)$europe.file
print("Finishing reactive function 'Data'")
return(list(data = myx, europe = europe))
})
#----------------------------------------------------------------------
# Main function that should read in the input and 'calculate' stuff
# after the users clicks on the button 'do_it' - takes about 20 sec
#----------------------------------------------------------------------
main_calc <- eventReactive(input$do_it, {
req(input$file_x)
# Reading in the input file:
x <- Data()$data
print("Done reading in the data inside main_calc")
# Running useless calculations - just to kill time:
myvector <- matrix(unlist(x), ncol = 1, nrow = 1000)
print("Starting calculations")
for (i in seq_len(10)) {
set.seed(12)
mymatr <- matrix(abs(rnorm(1000000)), nrow = 1000)
temp <- solve(mymatr) %*% myvector
}
print("Finished calculations")
# Creating a new file:
y <- temp
result = list(x = x, y = y)
print("End of eventReactive function main_calc.")
return(result)
}) # end of main_calc
#----------------------------------------------------------------------
# The user should be able to save the output of main_calc as a csv file
# using a string s/he specified for the file name:
#----------------------------------------------------------------------
output$file_down <- downloadHandler(
filename = function() {
paste0(input$user_filename, " ", Sys.Date(), ".csv")
},
content = function(file) {
print("Europe Flag is:")
print(Data()$europe)
if (Data()$europe == 1) {
x_out <- main_calc()$x
print("Dimensions of x in downloadHandler are:")
print(dim(x_out))
write.csv2(x_out,
file,
row.names = FALSE)
} else {
x_out <- main_calc()$x
print("Dimensions of x in downloadHandler are:")
print(dim(x_out))
write.csv(x_out,
file,
row.names = FALSE)
}
}
)
} # end of server code
shinyApp(ui, server)
Below is the solution - based on MrFlick's suggestions:
# generate file 'x.csv' to read in later in the app:
# write.csv(data.frame(a = 1:4, b = 2:5), "x.csv", row.names = F)
# write.csv2(data.frame(a = 1:4, b = 2:5), "x_Europe.csv", row.names = F)
library(shiny)
library(shinyjs)
ui <- fluidPage(
# User should upload file x here:
fileInput("file_x", label = h5("Upload file 'x.csv'!")),
br(),
actionButton("do_it", "Click Here First:"),
br(),
br(),
textInput("user_filename","Save your file as:", value = "My file x"),
downloadButton('file_down',"Save the output File:")
)
server <- function(input, output, session) {
#----------------------------------------------------------------------
# Function to read in either European (csv2) or American (csv) input:
#----------------------------------------------------------------------
ReadFile <- function(pathtofile, withheader = TRUE){
test <- readLines(pathtofile, n = 1)
if (length(strsplit(test, split = ";")[[1]]) > 1) {
print("Reading European CSV file")
outlist <- list(myinput = read.csv2(pathtofile, header = TRUE),
europe.file = 1)
} else {
print("Reading US CSV file")
outlist <- list(myinput = read.csv(pathtofile, header = TRUE),
europe.file = 0)
}
return(outlist)
}
#----------------------------------------------------------------------
# Data-related - getting the input file
#----------------------------------------------------------------------
Data <- reactive({
print("Starting reactive function Data")
# Input file:
infile_x <- input$file_x
myx <- ReadFile(infile_x$datapath)$myinput
# European file?
europe <- ReadFile(infile_x$datapath)$europe.file
print("Finishing reactive function 'Data'")
return(list(data = myx, europe = europe))
})
#----------------------------------------------------------------------
# Main function that should read in the input and 'calculate' stuff
# after the users clicks on the button 'do_it' - takes about 20 sec
#----------------------------------------------------------------------
# Creating reactive Values:
forout_reactive <- reactiveValues()
observeEvent(input$do_it, {
print("STARTING observeEvent")
req(input$file_x)
# Reading in the input file:
x <- Data()$data
print("Done reading in the data inside observeEvent")
# Running useless calculations - just to kill time:
myvector <- matrix(unlist(x), ncol = 1, nrow = 1000)
print("Starting calculations")
for (i in seq_len(10)) {
set.seed(12)
mymatr <- matrix(abs(rnorm(1000000)), nrow = 1000)
temp <- solve(mymatr) %*% myvector
} # takes about 22 sec on a laptop
print("Finished calculations")
# Creating a new file:
y <- temp
forout_reactive$x = x
forout_reactive$y = y
print("End of observeEvent")
}) # end of main_calc
#----------------------------------------------------------------------
# The user should be able to save the output of main_calc as a csv file
# using a string s/he specified for the file name:
#----------------------------------------------------------------------
output$file_down <- downloadHandler(
filename = function() {
paste0(input$user_filename, " ", Sys.Date(), ".csv")
},
content = function(file) {
print("Europe Flag is:")
print(Data()$europe)
if (Data()$europe == 1) {
y_out <- forout_reactive$y
print("Dimensions of y in downloadHandler are:")
print(dim(y_out))
write.csv2(y_out,
file,
row.names = FALSE)
} else {
y_out <- forout_reactive$y
print("Dimensions of y in downloadHandler are:")
print(dim(y_out))
write.csv(y_out,
file,
row.names = FALSE)
}
}
)
} # end of server code
shinyApp(ui, server)
Here is a simple app that may help elucidate how eventReactive() works:
library(shiny)
run_data <- function() {
paste0("Random number generated in eventReactive: ", runif(1))
}
ui <- basicPage(
actionButton("run1", "Invalidate eventReative()"),
actionButton("run2", "Trigger observeEvent()"),
verbatimTextOutput("data")
)
server <- function(input, output, session) {
# Initialize reactiveValues list
# to use inside observeEvent()
rv <- reactiveValues(data = NULL)
# This eventReactive() doesn't run when run1 button is
# clicked. Rather, it becomes invalidated. Only when
# data() (the reactive being returned) is actually
# called, does the expression inside actually run.
# If eventReactive is not invalidated by clicking run1
# then even if data() is called, it still won't run.
data <- eventReactive(input$run1, {
showNotification("eventReactive() triggered...")
run_data()
})
# Every time run2 button is clicked,
# this observeEvent is triggered and
# will run. If run1 is clicked before run2,
# thus invalidating the eventReactive
# that produces data(), then data() will
# contain the output of run_data() and
# rv$data will be assigned this value.
observeEvent(input$run2, {
showNotification("observeEvent() triggered")
rv$data <- data()
})
# Renders the text found in rv$data
output$data <- renderText({
rv$data
})
}
shinyApp(ui, server)
In this example, run1 invalidates the eventReactive(), and run2 triggers the observeEvent() expression. In order for the data (in this case just a random number) to print, run1 must be clicked prior to run2.
The key takeaway is that the input(s) (buttons) that eventReactive() listens to don't trigger eventReactive(). Instead, they invalidate eventReactive() such that when the output from eventReactive() is required, then the expression inside eventReactive() will run. If it is not invalidated or the output is not needed, it will not run.
I’m trying to format the output file from Vissim simulation to csv file. So I have 2 Fileinputs:
FileInput 1 is for formatting the FZP file to CSV file, it can be uploaded multiple file but for now it can only upload 2 at max, but later on I would like the FileInput 1 can process more than 2 files.
FileInput 2 is for merging the CSV file after converting the FZP file, because 1 run of VISSIM simulation can be multiple FZP files, so if I want to merge 2 runs or more I would like to use the FileInput 2 for merging it.
And my problem is in FileInput 1 because when I upload 2 files FZP it’s not causing an error, but when I only upload 1 file FZP it cause an error ‘Subscript Out of Bound’ even I already made a condition where the FileInput 1 in index 2 is Null then create new dataframe. Because, I’m trying to access individual file from the multiple uploaded file for calculating average of attributes in the FZP file by attribute called ‘VEHTYPE’.
So, how would I solve this?
#UI
library(shiny)
library(data.table)
shinyUI(fluidPage(
titlePanel("File Input"),
sidebarLayout(
sidebarPanel(
tags$hr(),
fileInput("file1",
"Choose FZP files",
multiple = TRUE),
fileInput("file2",
label="Upload multiple CSVs here",
multiple = TRUE),
uiOutput("column_1"),
downloadButton("download", "Filter Table"),
downloadButton("download1", "Aggregate Table")
),
mainPanel(
uiOutput("tb")
))
))
#Server
library(shiny)
library(dplyr)
library(plyr)
library(data.table)
shinyServer(function(input, output) {
data1 <- reactive({
inFile <- input$file1
if (is.null(inFile)) {
return(NULL)
} else {
inFile %>%
rowwise() %>%
do({
df <- fread(input$file1[[1, 'datapath]]', skip="t;", sep = ";", header=T, stringsAsFactor = F)
})
}
})
data2 <- reactive({
inFile <- input$file1
if (is.null(input$file1[[2, "datapath"]])) {
subData <- data1()
df <- subData[0,]
df
#data1()
} else {
inFile %>%
rowwise() %>%
do({
df <- fread(input$file1[[2, 'datapath']], skip="t;", sep = ";", header=T, stringsAsFactor = F)
})
}
})
output$column_1 <- renderUI({
if (is.null(data1())) {
return(NULL)
} else {
selectInput("column1", "Feature selection:", names(data1()))
}
})
average1 <- reactive({
#Processing data1
subsetData1 <- data1()
calAvg1 <- subsetData1[, c("VEHTYPE",input$column1)]
calAvg1 <- aggregate(calAvg1[, ncol(calAvg1)], list(VEHTYPE = calAvg1$VEHTYPE), mean)
total <- sum(calAvg1[, ncol(calAvg1)])/length(calAvg1$VEHTYPE)
dfTotal1 <- data.frame("Total", total)
names(dfTotal1) <- c("VEHTYPE", input$column1)
newDF1 <- rbind(calAvg1, dfTotal1)
})
average2 <- reactive({
#Processing data2
subsetData2 <- data2()
if(is.data.frame(subsetData2) && nrow(subsetData2)==0){
subsetData2
}else{
calAvg2 <- subsetData2[, c("VEHTYPE",input$column1)]
calAvg2 <- aggregate(calAvg2[, ncol(calAvg2)], list(VEHTYPE = calAvg2$VEHTYPE), mean)
total <- sum(calAvg2[, ncol(calAvg2)])/length(calAvg2$VEHTYPE)
dfTotal2 <- data.frame("Total", total)
names(dfTotal2) <- c("VEHTYPE", input$column1)
newDF2 <- rbind(calAvg2, dfTotal2)
}
})
finalDF <- reactive({
if(is.data.frame(average2()) && nrow(average2())==0){
average1()
}else{
final <- rbind(average1(), average2())
#average2()
}
#Merge all dataframe
#finalDF <- rbind(average1(), average2())
})
data3 <- reactive({
req(input$file2) ## ?req # require that the input is available
multiFile <- input$file2
df <- rbindlist(lapply(multiFile$datapath, fread),
use.names = TRUE, fill = TRUE)
as.data.frame(df)
return(df)
})
output$original <- renderDataTable({
data1()
})
output$filterData <- renderTable({
finalDF()
})
output$multiData <- renderTable({
data3()
})
output$download <- downloadHandler(
filename = function(){
paste("data-", Sys.Date(), ".csv", sep = "")
},
content = function(file){
write.csv(get_table(), file,row.names = F)
}
)
output$download1 <- downloadHandler(
filename = function(){
paste("data-", Sys.Date(), ".csv", sep = "")
},
content = function(file){
write.csv(data3(), file,row.names = F)
}
)
output$tb <- renderUI({
tabsetPanel(tabPanel("Original Data", dataTableOutput("original")),
tabPanel("Filter Data", tableOutput("filterData")),
tabPanel("Aggregate Data", tableOutput("multiData"))
)
})
})
FZP files look more or less like this:
$VISION
* File: Y:\03_Studentische Arbeiten\VT\IDP\Windu\Test Simulation\test1.inpx
* Comment:
* Date: 03.08.2017 09:32:43
* PTV Vissim: 9.00 [04]
*
* Table: Vehicles In Network
*
* SIMSEC: SimSec, Simulation second (Simulation time [s]) [s]
* NO: No, Number (Number of the vehicle)
* LANE\LINK\NO: Lane\Link\No, Lane\Link\Number (Unique number of the link or connector)
* LANE\INDEX: Lane\Index, Lane\Index (Unique number of the lane)
* POS: Pos, Position (Distance on the link from the beginning of the link or connector) [m]
* POSLAT: PosLat, Position (lateral) (Lateral position at the end of the time step. Value range 0 - 1: 0: at the right lane edge 0.5: middle of the lane 1: at the left lane edge)
* EMISSIONSCO2: EmissionsCO2, Emissions CO2 (Quantity of carbon monoxide [grams / sec])
* EMISSIONSNOX: EmissionsNOx, Emissions NOx (Quantity of nitrogen oxides [grams / sec])
* FUELCONSUMPTION: FuelConsumption, Fuel consumption (Fuel consumption [US liquid gallon])
* INQUEUE: InQueue, In queue (Returns if the vehicle is in queue. Queue is defined by speed and headway treshholds. (see queue definition))
* NUMSTOPS: NumStops, Number of stops (Number of stops (cumulative): all situations in which a vehicle comes to a standstill (speed = 0), except stops at PT stops and in parking lots)
* SPEED: Speed, Speed (Speed at the end of the time step) [km/h]
* VEHTYPE: VehType, Vehicle type (Select Vehicle type from the list box)
*
* SimSec; No; Lane\Link\No; Lane\Index; Pos; PosLat; EmissionsCO2; EmissionsNOx; FuelConsumption; InQueue; NumStops; Speed; VehType
*
$VEHICLE:SIMSEC;NO;LANE\LINK\NO;LANE\INDEX;POS;POSLAT;EMISSIONSCO2;EMISSIONSNOX;FUELCONSUMPTION;INQUEUE;NUMSTOPS;SPEED;VEHTYPE
0.50;1;1;1;0.80;0.50;;;;0;0;41.70;100
0.60;1;1;1;1.96;0.50;;;;0;0;41.90;100
0.70;1;1;1;3.13;0.50;;;;0;0;42.16;100
0.80;1;1;1;4.31;0.50;;;;0;0;42.50;100
0.90;1;1;1;5.49;0.50;;;;0;0;42.91;100
1.00;1;1;1;6.69;0.50;;;;0;0;43.39;100
1.10;1;1;1;7.90;0.50;;;;0;0;43.92;100
1.20;1;1;1;9.13;0.50;;;;0;0;44.44;100
1.30;1;1;1;10.37;0.50;;;;0;0;44.96;100
1.40;1;1;1;11.63;0.50;;;;0;0;45.48;100
1.50;1;1;1;12.90;0.50;;;;0;0;45.99;100
1.60;1;1;1;14.18;0.50;;;;0;0;46.49;100
1.70;1;1;1;15.48;0.50;;;;0;0;47.00;100
1.80;1;1;1;16.79;0.50;;;;0;0;47.50;100
Error
Warning: Error in [[: subscript out of bounds
Stack trace (innermost first):
117: [[.data.frame
116: [[
115: fread
114: overscope_eval_next
113: do.rowwise_df
112: do
111: function_list[[k]]
110: withVisible
109: freduce
108: _fseq
107: eval
106: eval
105: withVisible
104: %>%
103: <reactive:data2>
92: data2
91: <reactive:average>
80: average
79: renderTable
78: func
77: origRenderFunc
76: output$filterData
1: shiny::runApp
I think that the problem is in the assignment of the file to the data frame, I fixed a bit the code there.
Try changing the server code in the following way and let me know whether it works.
shinyServer(function(input, output) {
data1 <- reactive({
inFile <- input$file1
if (is.null(inFile)) {
return(NULL)
} else {
inFile %>%
rowwise() %>%
do({
df <- fread(input$file1$datapath, skip="t;", sep = ";", header=T, stringsAsFactor = F)
})
}
})
data2 <- reactive({
inFile <- input$file1
if (is.null(inFile)) {
return(NULL)
} else {
inFile %>%
rowwise() %>%
do({
df <- fread(input$file2$datapath, skip="t;", sep = ";", header=T, stringsAsFactor = F)
})
}
})
output$column_1 <- renderUI({
if (is.null(data1())) {
return(NULL)
} else {
selectInput("column1", "Feature selection:", names(data1()))
}
})
To convert .fzp files to .txt or .csv just use DOS command prompt.
You can navigate to your folder and use the following syntax:
ren *.fzp *.txt
or
ren *.fzp *.csv
after that, follow the steps on this page reading from folder
and use read.csv with "skip= " to read your files.
I'm trying to populate a data.frame/matrix based on some user-defined rules. I managed to create a function in R, but am stuck trying to replicate this as a Shiny app [it's my first time using Shiny, and I'm an idiot to start with this one]
This is the crux of the code in regular r-script -
user-inputs are: size (1~3), changes (1~2) and iterations (10~1000)
school_choice_function<- function(changes, size, iterations )
{
######## 1509
##### List of schools
p<-1
j<-1
k<-1
l<-1
s_list<- rep(0,80)
for (i in 1:80) {
if (i <= 26) {
schl<- paste(LETTERS[p],LETTERS[i],sep = "")
s_list[i]<- schl }
if (i>26 & i<=52) {p<- 2
schl<- paste(LETTERS[p],LETTERS[j],sep = "")
s_list[i]<- schl
j=j+1}
if (i>52 & i<=78) {p<- 3
schl<- paste(LETTERS[p],LETTERS[k],sep = "")
s_list[i]<- schl
k=k+1}
if (i>78 ) {p<- 4
schl<- paste(LETTERS[p],LETTERS[l],sep = "")
s_list[i]<- schl
l=l+1}
}
rm(p,i,j,k,l)
########## Applicant Data
a<- c(2011:2015)
c<- 1:size
d<- 1:changes
y<-0
v<-1
w<-10
mat <- matrix(ncol=5, nrow=(iterations*10))
for(pop in 1:iterations){
for (z in v:w)
{
b<- s_list[(1+y):(8+y)]
e<- rep(0,5)
e[1]<- b[1]
g<- sample(d,1)
h<- sample(2:5,g, replace = FALSE)
f1<- rep(0,length(h))
for(j in 1:g){
for(i in 1:length(h))
{
f<- sample(c, 1)
f1[i]<- paste(sample(b,f,replace = FALSE),collapse = ",")
e[h[i]]<- f1[i]
}
}
for(i in c(which(e %in% 0))){
e[i]<- e[i-1]
}
mat[z,]<- e
y<-y+8
}
v<- w+1
w<- w+10
y<-0
}
df<- data.frame(mat,stringsAsFactors = FALSE)
colnames(df)<- c("2011","2012","2013","2014","2015")
return(df)
}
Ignoring the use of worst-practices in coding (I've just learnt to think in terms of loops), I'm using this is a shiny app like this. "s_list/schools" is a character matrix with 80 elements, created before this code.
Just so you get an intuition of what on earth is this - basically it is applicant data over 5 years, who may or many not get assigned to alternatives over time, (based on the rules which comes through in the loops).
The code works in the current form - except the output table is full of NAs.... Any kind of help would be a step up from where I'm at!
ui<- fluidPage(
numericInput(inputId="Changes", label="Changes", value=1, min = 1, max = 3, step = 1),
numericInput(inputId="Size", label="Size", value=2, min = 1, max = 3, step = 1),
numericInput(inputId="Iterations", label="Iterations", value=10, min = 10, max = 1000, step = 10),
tableOutput("dframe")
)
server<- function(input,output) {
Changes<- reactive({input$Changes})
Size<- reactive({input$Size})
Iterations<- reactive({input$Iterations})
schools<- s_list
########## Applicant Data
a<- c(2011:2015)
cc<- reactive(1:(Size()))
d<- reactive(1:(Changes()))
y<-0
v<-1
w<-10
mat <- reactive(matrix(ncol=5, nrow=((input$Iterations)*10)))
pop<- 0
z<- 0
i<- 0
j<- 0
this<- reactive({
for(pop in 1:(Iterations())){
for (z in v:w)
{
b<- schools[(1+y):(8+y)]
e<- rep(0,5)
e[1]<- b[1]
g<- reactive(sample(d(),1))
h<- reactive(sample(2:5,g(), replace = FALSE))
f1<- reactive(rep(0,length(h())))
for(j in 1:g()){
for(i in 1:length(h()))
{
f<- reactive(sample(cc(), 1))
f1()[i]<- reactive(paste(sample(b,f(),replace = FALSE),collapse = ","))
e[h()[i]]<- f1()[i]
}
}
for(i in cc()(which(e %in% 0))){
e[i]<- e[i-1]
}
mat()[z,]<- e
y<-y+8
}
v<- w+1
w<- w+10
y<-0
}
})
df<- reactive(data.frame(mat(),stringsAsFactors = FALSE))
output$dframe <- renderTable({ df() })
}
shinyApp(ui= ui, server = server)
Instead of writing the whole code of the function school_choice_function inside your server why don't you define the function outside your server and just call it from inside your server. Something like this:
server<- function(input,output) {
Changes<- reactive({input$Changes})
Size<- reactive({input$Size})
Iterations<- reactive({input$Iterations})
df<- reactive({
df <- school_choice_function(Changes(), Size(), Iterations())
return(data.frame(df, stringsAsFactors = FALSE))
})
output$dframe <- renderTable({ df() })
}
I am trying to build a GUI using gWidgets R library to download satellite imagery. The intention is to read the urls from a comma separated values file. The GUI looks ok but it does not do what I expect it to do. I am doing something wrong, any help is greatly appreciated.
Here is the sample data:
Online.Access.URLs <- c("http://e4ftl01.cr.usgs.gov//MODIS_Composites/MOLT/MOD09A1.005/2000.02.18/MOD09A1.A2000049.h09v06.005.2006268183648.hdf",
"http://e4ftl01.cr.usgs.gov//MODIS_Composites/MOLT/MOD09A1.005/2000.02.26/MOD09A1.A2000057.h09v06.005.2006270065224.hdf",
"http://e4ftl01.cr.usgs.gov//MODIS_Composites/MOLT/MOD09A1.005/2000.03.05/MOD09A1.A2000065.h09v06.005.2006269234536.hdf")
Producer.Granule.ID <- c("MOD09A1.A2000049.h09v06.005.2006268183648.hdf",
"MOD09A1.A2000057.h09v06.005.2006270065224.hdf",
"MOD09A1.A2000065.h09v06.005.2006269234536.hdf")
df <- data.frame(Producer.Granule.ID,Online.Access.URLs)
write.csv(df,"C:\\GUI_test\\h09v06v3.csv",row.names=FALSE)
And this is my try:
my.DownloadHDF <- function(){
library(gWidgets)
library(gWidgetstcltk)
library(RCurl)
options(guiToolkit = "tcltk")
win <- gwindow("Download HDF with R!", visible = FALSE)
csv.frame <- gframe("csv file ", container = win)
csv.label <- glabel("csv with HDF's names ", container = csv.frame)
csv.file.name <- gfilebrowse("Select csv file", type="open",cont=csv.frame,action="read.csv")
dir.frame <- gframe("Output Directory ", container = win)
dir.label <- glabel("Where to save HDF's? ", container = dir.frame)
dir.out <- gfilebrowse("Select folder ",type = "selectdir", cont=dir.frame)
dlw.frame <- gframe("Download ", container = win)
dlw.label <- glabel(" ", container = dlw.frame)
btnDwn <- gbutton("Start Download", container = dlw.frame,
handler = function(csv.file.name,dir.out){
df <- read.csv(csv.file.name, header=TRUE,sep=",")
hdf.urls <- df$Online.Access.URLs
hdf.urls <- as.character(hdf.urls)
hdf.names <- df$Producer.Granule.ID
hdf.names <- as.character(hdf.names)
for (i in 1:length(hdf.names)){
URL <- hdf.urls [i]
file <- hdf.names[i]
download.file(URL,paste(dir.out,file,sep=""),mode="wb")
cat(paste("Composite number ",i,"successfully downloaded!"),sep="\n")
cat("\n\n\n\n\n\n\n\n")
}})
visible(win) <- TRUE
}
my.DownloadHDF()
I am using R-3.2.2 with RStudio 0.98.1103.
Here is the script after the improvements. Now it does exactly what I expect it to do. I hope someone finds it useful:
# load functions ####
# download function
f.d <- function(hdf.urls,hdf.names,out.dir){
for(i in 1:length(hdf.urls)){
URL <- hdf.urls [i]
file <- hdf.names [i]
download.file(URL,paste(out.dir,"/",file,sep=""),mode="wb")
}}
# read csv function
f.csv <- function(x){
df1 <<- read.csv(x,header=TRUE,sep=",")
hdf.urls <<- df1$Online.Access.URLs
hdf.urls <<- as.character(hdf.urls)
hdf.names <<- df1$Producer.Granule.ID
hdf.names <<- as.character(hdf.names)
}
# load functions ####
# my.DownloadHDFv2 this one works fine ####
my.DownloadHDF <- function(){
options(guiToolkit = "tcltk")
win <- gwindow("Download HDF with R!", visible = FALSE)
csv.frame <- gframe("csv with HDFs names ", container = win)
a <- gfilebrowse("Upload csv file",cont=csv.frame,
handler=function(h,...){
f.csv(svalue(a))
})
path.frame <- gframe("Output Directory ", container = win)
brow <- gfilebrowse(text = "Select folder...", type = "selectdir",container=path.frame,
handler=function(h,...){
out.dir <<- svalue(brow)
})
b <- gbutton(text="Start Download",container = win,
handler = function(h,...){
f.d(hdf.urls,hdf.names,out.dir=out.dir)
})
visible(win)<-TRUE
}
my.DownloadHDF()
# my.DownloadHDFv2 this one works fine ####