Ajatellaan esim. tilannetta, jossa osasto X pyytää usein listoja, koska listalle kuuluvat yritykset vaihtuvat tiuhaan tahtiin. Analyytikolle tämä tarkoittaa SQL-kyselyn muokkaamista, ajamista sekä valmiin tiedoston lähettämistä. Aikaa tähän kaikkeen ei välttämättä mene kuin 15-30min, mutta yllättävä aikasyöppö voi olla epätäydellinen informaatio. Ymmärsikö analyytikko tarpeet oikein? Vai unohtiko listan pyytäjä sanoa jotain ja täten lista pitää tehdä uusiksi? Tällaisen pienen työn tekeminen voi lopulta viedä paljon enemmän aikaa, ja kun tätä tapahtuu usein, niin kuukaudessa puhutaan jo huomattavista ajallisista kustannuksista.
Mikä avuksi?
1. Sovitaan tietyt listat automatisoitaviksi esim. kuukausittain. Tällöin aikaa säästyy, mutta toisaalta lista pysyy samana, eli siihen ei pysty tekemään muokkauksia ilman analyytikon välikättä.
2. Parannetaan informaation kulkua, jotta ei tule väärinkäsityksiä. Keskustellaan steikkareiden kanssa rohkeasti, jotta jatkossa listan pyytäjä näkee vain valittavat pizzatäytteet, eli tehdään valinnasta helppoa.
3. Mietitään voisiko listan toteuttaa niin, että listan pyytäjä voisi tehdä muokkaukset ja listan haut itse. Tässä kohtaa RStudion Shiny voi olla suureksi avuksi.
Mikä on Shiny?
Shiny on R-paketti, jolla voi tehdä interaktiivisia web-applikaatioita suoraan R:n kautta. Käytännössä loppukäyttäjä näkee nettisivun, jossa hän voi valita esim. tietyn tuotteen myynnit haluamilleen vuosille. Shiny mahdollistaa siis samoja asioita kuin PowerBi ja Qlik Sense, eli helpottaa tiedon hakua. Shinyn etu edellä mainittuihin työkaluihin on, että sillä voi tehdä kaikkea mitä ärrässäkin voi, eli se mahdollistaa mm. tehokkaammat visualisoinnit.
Shiny apuna listojen teossa
Shinylla pystyy tekemään näkymän, jossa loppukäyttäjä voi valita esim. kaikki asiakkaat, jotka ovat ostaneet tuotetta X. SQL-muodossa tämä tarkoittaa, että loppukäyttäjä pystyy valitsemaan tuotteet, jotka analyytikko muuten syöttäisi manuaalisesti "Where"-lausekkeeseen. Shinylla loppukäyttäjä pystyy siis syöttämään haluamansa kriteerit SQL-lausekkeeseen selkeän käyttöliittymän avulla.
Alla näkymä tekemästäni esimerkkiäpistä. Käyttäjän kaikki valinnat ovat yhteydessä SQL-kyselyyn. Alla olevalla työkalulla käyttäjä pystyy valitsemaan yrityslistan (esim. kohderyhmät) toimialan ja toteutuneiden myyntien perusteella. Lopuksi käyttäjä voi lähettää valmiin listan excelinä.
Miten tällainen työkalu tehdään?
Luodaan ensin tietokanta MySQL:ssä.
create database datamyynnit;
use datamyynnit;
create table asiakkuudet (asiakasID int(10) unsigned auto_increment primary key not null,
Kaupunki varchar(30) not null, Puhelinnumero varchar(20) not null, Toimiala varchar(10) not null);
create table myynnit(asiakasID int(10) not NULL, tilausnumero int(10) unsigned primary key not null,
maara int(10) not null, tuote varchar(30) not null,hinta int(10) not null, pvm date not null);
insert into asiakkuudet (Kaupunki,Puhelinnumero,Toimiala) values("Espoo","034343434","A");
insert into asiakkuudet (Kaupunki,Puhelinnumero,Toimiala) values("Helsinki","032004332","A");
insert into asiakkuudet (Kaupunki, Puhelinnumero,Toimiala) values("Espoo","034363555","B");
insert into asiakkuudet (Kaupunki, Puhelinnumero,Toimiala) values("Helsinki","035545555","B");
insert into myynnit (asiakasID,tilausnumero,maara,tuote,hinta,pvm) values("2","15","1","tuote1","900","2019-09-10");
insert into myynnit (asiakasID,tilausnumero,maara,tuote,hinta,pvm) values("1","16","1","tuote2","800","2019-09-15");
insert into myynnit (asiakasID,tilausnumero,maara,tuote,hinta,pvm) values("1","17","1","tuote1","900","2019-09-15");
insert into myynnit (asiakasID,tilausnumero,maara,tuote,hinta,pvm) values("3","18","1","tuote2","800","2019-09-28");
insert into myynnit (asiakasID,tilausnumero,maara,tuote,hinta,pvm) values("3","19","1","tuote1","900","2019-09-26");
insert into myynnit (asiakasID,tilausnumero,maara,tuote,hinta,pvm) values("4","20","1","tuote1","900","2019-09-25");
Esim.
sqltk = dbConnect(MySQL(), user='root', password='1234', dbname='datamyynnit', host='localhost')
dbGetQuery(sqltk,"select * from myynnit")
Seuraavaksi on luotava Shinylla UI:
library(shiny)
library(dbConnect)
library(RMySQL)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
titlePanel("Kohderyhmätyökalu"),
sidebarLayout(
sidebarPanel(
helpText("Valitse haluamasi kohderyhmä valikoista ja klikkaa lopuksi 'Printtaa excelinä'-painiketta."),
selectInput("tol",
label=("Toimiala"),
choices = c("Voit valita useita"='',c("TOL A" ="A",
"TOL B"="B")),
multiple=T, selected=c("A","B")
),
selectInput("tuote",
label=("Myynnit tuotteille"),
choices = c("Voit valita useita"='',c("Tuote 1" ="tuote1",
"Tuote 2"="tuote2")),
multiple=T,selected=c("Tuote 1"="tuote1",
"Tuote2"="tuote2")),
dateRangeInput("dates",
label = ("Myyntien aikaväli"),
start = Sys.Date() - 90, end = Sys.Date() - 1,
format = "yyyy-mm-dd",
language = "fi",
separator = "-"
),
#minimimyynti
sliderInput("minmyynti", "Minimimyynti:",
min = 0, max = 10000, value = 0
)
,
actionButton("printti", "Printtaa excelinä")
,
hr(),
#Lisätään "submitButton", jotta kyselyä ei ajeta jokaisen muutoksen jälkeen automaattisesti.
submitButton("Päivitä",icon("refresh"),width="200px"),
helpText("Klikkaamalla yllä olevaa painiketta hakusi ajetaan",style ="font-size:15px; color:red")
),
mainPanel(
h1("Kohderyhmälista"),
tableOutput("tableready")
)
)
))
Liitetään seuraavaksi Server-puoli mukaan:
shinyServer(function(input,output) {
sqltk = dbConnect(MySQL(), user='root', password='1234', dbname='datamyynnit', host='localhost')
table <- reactive ({
tol_selected <- paste0("'",input$tol,"'",collapse=",")
tuote_selected <- paste0("'",input$tuote,"'",collapse=",")
#stringr::str_c(stringr::str_c("'",input$tol,"'"), collapse = ',')
dbGetQuery(sqltk,
#paste0("select * from asiakkuudet where Toimiala in (",tol_selected,")")
gsub(paste0("select asiakkuudet.*, IFNULL(myynnit2.myynniteur,0) as myynniteur from asiakkuudet
left join
(
SELECT asiakasID as asID, sum(hinta) as myynniteur FROM myynnit where tuote in (",tuote_selected,")
and pvm >= '",input$dates[1],"' AND pvm <= '",input$dates[2],"' group by asiakasID
)
as myynnit2 on myynnit2.asID=asiakkuudet.asiakasID
where asiakkuudet.Toimiala in (", tol_selected,")
and IFNULL(myynnit2.myynniteur,0) >=",input$minmyynti)
,pattern="\n",replacement=" ")
) })
observeEvent(input$printti, {
showModal(modalDialog(
title = "Kohderyhmälistasi on nyt valmis!",
"Muista käyttää minua myös jatkossa :)",
footer = modalButton("Sulje")
))
#Excelin printtaus
dttt <- data.frame(table())
dttt$asiakasID <- as.integer(dttt$asiakasID)
dttt$Puhelinnumero <- as.character(dttt$Puhelinnumero)
#Valitaan sijainti, johon printatut excelit menevät
write.csv2(dttt,'C:/Users/aleksi/Documents/testila3.csv', row.names = FALSE)
})
output$tableready <- renderTable({
dt <- data.frame(table())
dt$asiakasID <- as.integer(dt$asiakasID)
dt
})
}
)
#Alla oleva koodipätkä katkaisee yhteydet, kun sessio lopetetaan.
killDbConnections <- function () {
all_cons <- dbListConnections(MySQL())
print(all_cons)
for(con in all_cons)
+ dbDisconnect(con)
print(paste(length(all_cons), " connections killed."))
}
killDbConnections()
Nyt kun työkalu on valmis, katsotaan hieman sen toimintaa. Esim. Valitaan vain ne toimialan "A" yritykset, joilla on ollut viimeisen kuukauden aikana myyntiä tuotteelle 1 vähintään 500€:lla. Alla kuva haun lopputuloksesta. Aikaa filttereiden valitseminen vei vain muutaman sekunnin, joten aikaa säästyi verrattaen, kuin jos oltaisiin pyydetty analyytikkoa hakemaan tämä tieto manuaalisesti tietokannasta.
Ei kommentteja:
Lähetä kommentti