Hi,
I'm currently using R Shiny to build dashboard with reticulate package to link to Python code.
Here I'm using 4 output from Python functions written in .py file, functions including output_budget(), output_w1(), output_w2(), output_crane_percentage().
The app.R file look like this:
library(reticulate)
library(shiny)
use_virtualenv("~/.virtualenvs/Vpy37")
use_python("/usr/local/bin/python3")
reticulate::use_python("/usr/bin/python3")
reticulate::py_config()
ui <- fluidPage(
inputPanel(
headerPanel(title="DHQCs & Spreaders expenditure apportionment"),
dateInput(inputId = "year",label="Select Current Year",value = "2020-01-01",
format = "yyyy",min="2019-01-01",max = "2020-01-01",
startview = "year", autoclose=TRUE),
selectInput(inputId = "terminalID",label = "Select Terminal",
choices = list("PPT2ED","PPT3ED"), selected = "PPT2ED"),
numericInput(inputId = "CCPB",label="Input CCPB($)",value=0.6,
min = 0, max=NA, step=NA),
numericInput(inputId = "VOLUME",label="Input Volume",value=60000,
min=50000, max=100000)
),
mainPanel(
textOutput("textOutput1"),
textOutput("textOutput2"),
textOutput("textOutput3"),
tableOutput("crane_table")
)
)
source_python("panel1.py")
server=function(input,output){
#two text two table to display
output$textOutput1<-renderText({
returnedText=output_budget(CCPB=input$CCPB,volume=input$VOLUME)})
output$textOutput2<-renderText({
expr=output_w1(year=input$year,terminal=input$terminalID)
})
output$textOutput3<-renderText({
output_w2(year=input$year,terminal=input$terminalID)
})
output$crane_table<-renderTable({
output_crane_percentage(year=input$year,terminal=input$terminalID)
})
}
shinyApp(ui,server)
And the panel1.py is here:
-------Python code------
## import packages
import pandas as pd
## set directory and read file
c_dir = 'C:/Users/WY483TU/OneDrive - EY/Desktop/PSA UI'
data_p1 = pd.read_excel(c_dir + '/R Shiny/development/dashboard/data_requirement_backup.xlsx')
#---------------data manipulation---------------
## adding sum of weights for each batch
a_lst = []
for index, row in data_p1.iterrows():
a_lst.append((row["Expense on Maintenance"]+row["Expense on Refurbishment"]+row["Expense on Repair"]))
data_p1['An%'] = a_lst
## display form in percentage for float var
data_p1_d = data_p1.copy()
for i in data_p1_d.columns:
if (i.startswith('E')) or (i=='An%'):
data_p1_d[i] = pd.Series(["{0:.2f}%".format(val * 100) for val in data_p1_d[i]],
index = data_p1_d.index)
#---------------dashboard output functions---------------
## function to show budget
def output_budget(CCPB, volume):
budget = CCPB*volume
return "Last year's total budget is: " +str(budget)
## function to show weights w1 and w2
def output_w1(year, terminal, df=data_p1):
w1 = float(0)
#w2 = float(0)
for index, row in data_p1.iterrows():
# filter based on user input
#last_year = int(year)-1
if (row['Terminal'] == terminal) & (row['Year']==year):
if row['Identity'] != 'Spreader':
w1 = w1+row['An%']
w1 =round(w1,2)
#w2 = 1-w1
str1 = "xxxxs expenditure apportionment(last year): "+"{0:.2f}%".format(w1 * 100)
#str2 = "Spreaders: "+"{0:.2f}%".format(w2 * 100)
return str1
def output_w2(year, terminal, df=data_p1):
w1 = float(0)
w2 = float(0)
for index, row in data_p1.iterrows():
# filter based on user input
if (row['Terminal'] == terminal) & (row['Year']==year):
if row['Identity'] != 'Spreader':
w1 = w1+row['An%']
w1 =round(w1,2)
w2 = 1-w1
#str1 = "DHQCs expenditure apportionment(last year): "+"{0:.2f}%".format(w1 * 100)
str2 = "Spreaders: "+"{0:.2f}%".format(w2 * 100)
return str2
## function to show individual batch weights
def output_crane_percentage(year,terminal,df=data_p1_d):
df = pd.DataFrame(columns=data_p1_d.columns)
# filter rows for selected year and terminal
for index, row in data_p1_d.iterrows():
if (row['Terminal'] == terminal) & (row['Year']==year):
if row['Identity']!='Spreader':
df = df.append(row,ignore_index=True)
# show desired columns in certain order
df = df.drop(['Terminal','Year'],axis=1)
# print(df.columns)
# print('_________________________________________')
df = df[['Identity','An%','Expense on Maintenance','Expense on Refurbishment','Expense on Repair']]
return df
## function to show individual spreader weights
def output_spreader_percentage(year,terminal,df=data_p1_d):
df = pd.DataFrame(columns=data_p1_d.columns)
# filter rows for selected year and terminal
for index, row in data_p1_d.iterrows():
if (row['Terminal'] == terminal) & (row['Year']==year-1):
if row['Identity']=='Spreader':
df = df.append(row,ignore_index=True)
# show desired columns in certain order
df = df.drop(['Terminal','Year','Identity','An%'],axis=1)
df = df[['Expense on Maintenance','Expense on Refurbishment','Expense on Repair']]
return df
------Python code end------
And to be clear, I did some data manipulation on data_p1 and data_p1_d inside panel1.py also.
Now the issue is, if I add "print(output_w1(xx,xx)" inside panel1.py, in R it gives correct output:
"xxxxs expenditure apportionment(last year): 86.00%
Spreaders: 14.00%"
But if in dashboard, it shows wrong number and not changing if I change year and terminal on the input panel, another issue is that output_crane_percentage() should return a dataframe(which it does if I run the py file), but does not displaying anything on dashboard:
Thanks in advance for any advice!