Nothing
library(shiny)
library(shinyjs)
#library(mgcv)
#library(lmtest)
#dist.custom <- .dist.custom
#dist.custom.veravar <- .dist.custom.veravar
#dist.custom.param <- .dist.custom.param
#wd=.wd
ui <- fixedPage(
shinyjs::useShinyjs(),
withMathJax(),
verticalLayout(
wellPanel(
fluidRow(
column(width=4,
tags$h1(id="titolo",HTML("Guess the line"))
),
column(width=6,
verticalLayout(
textOutput("testo1"),
textOutput("testo2")
)
),
column(width=2,
verticalLayout(
actionButton("aggiorna","Start",style="position: relative;height: 60px;width: 100%;text-align:center;color:black;font-weight: bold;background-color:#A8DEF0;border-radius: 6px;border-color:#35C4F0;border-width:9px;text-decoration:none"),
br(),
actionButton("show","Solution",style="position: relative;height: 60px;width: 100%;text-align:center;color:black;font-weight: bold;background-color:#A8DEF0;border-radius: 6px;border-color:#35C4F0;border-width:9px;text-decoration:none")
)
)
)),
fluidRow(
fillRow(plotOutput("grafico",
click = "plot_click",dblclick = "plot_dblclick"),
plotOutput("graficossq",
click = "plot_click",dblclick = "plot_dblclick"),
flex=c(4,1)
)
)
)
)
server <- function(input, output, session) {
disable("show")
rv=reactiveValues()
rv$show=0
rv$testo1="Try to guess the line of best fit for the points in the plot: click on the plot on two points to specify the line which goes through them: Click anywhere on the plot to choose the first point."
rv$x=c()
rv$y=c()
rv$sumsq=c()
rv$currsumsq=NA
rv$currbest=NA
rv$minsumsq=0
rv$numprova=0
rv$Error=c(NA,NA)
###########################################################################################
########
####### INPUT DEI PUNTI
shinyjs::click("aggiorna")
observe({
if (is.null(rv$xcoord)){
rv$xcoord=c() #c(0)
rv$ycoord=c() #c(0)
}
})
observeEvent(rv$numprova,{
if (rv$numprova>0) updateActionButton(session,"aggiorna",label="New")
})
observeEvent(input$aggiorna,{
rv$xcoord=c() #c(0)
rv$ycoord=c() #c(0)
rv$sumsq=c()
rv$currsumsq=NA
rv$currbest=NA
rv$testo1="Try to guess the line of best fit for the points in the plot: click on the plot on two points to specify the line which goes through them: Click anywhere on the plot to choose the first point."
rv$testo2=""
rv$show=0
rv$numprova=rv$numprova+1
n=trunc(runif(1,10,30))
sceltax=sample(1:pmin(3,rv$numprova),1)
if (sceltax==1) x=rnorm(n,0,1)
if (sceltax==2) x=runif(n,0,1)
if (sceltax==3) {
x=sample(c(-1,1),1)*rchisq(n,1)
}
x=(x-mean(x))/sd(x)
beta0=rnorm(1,0,10)
beta1=rnorm(1,0,10)
my=beta0+beta1*x
sceltaeV=sample(1:ifelse(rv$numprova>2,2,1),1)
if (sceltaeV==1) stdeverr=runif(1,0.5,1)*sd(my)
if (sceltaeV==2) stdeverr=runif(1,0.5,1)*abs(my)
sceltae=sample(1:ifelse(rv$numprova>2,3,1),1)
if (sceltae==1) errori=rnorm(n,0,stdeverr)
if (sceltae==2){
errori=sample(c(-1,1),1)*rchisq(n,sample(1:3,1))
errori=stdeverr*errori/sd(errori)
errori=errori-mean(errori)
}
if (sceltae==3){
errori=runif(n,-1,1)
errori=stdeverr*errori/sd(errori)
errori=errori-mean(errori)
}
y=beta0+beta1*x+errori
sceltaP=sample(1:6,1)
if ((sceltaP<4) & (rv$numprova>2)){
x0=sample(c(mean(x),mean(x)+c(1.5,0.5,-0.5,-1.5)*(max(x)-mean(x))),sceltaP,replace=TRUE)*rnorm(sceltaP,0,0.1*sd(x))
y0=beta0+beta1*x0+sample(c(2,3,4),sceltaP,replace=TRUE)*sample(c(-1,1),sceltaP,replace=TRUE)*mean(abs(errori))
x=c(x,x0)
y=c(y,y0)
}
y=(y-mean(y))/sd(y)
fit=lm(y~x)
prev=predict(fit,newdata=data.frame(x=x))
rv$fit=fit
rv$minsumsq=sum(resid(fit)^2)
#rv$testset=testset
rv$x=x
rv$y=y
})
rv$check=0
observeEvent(input$show,{
rv$show=1
})
observeEvent(rv$sumsq,{
if (length(rv$sumsq)>0){
shinyjs::enable("show")
} else {
shinyjs::disable("show")
}
})
observeEvent(input$plot_click$x,{
if (length(rv$xcoord)<2){
temp=rv$xcoord
temp=c(temp,input$plot_click$x)
rv$xcoord=temp
temp=rv$ycoord
temp=c(temp,input$plot_click$y)
rv$ycoord=temp
rv$testo1="Ok, now choose a second point."
} else {
new=c(input$plot_click$x,input$plot_click$y)
if (sum((new-c(rv$xcoord[1],rv$ycoord[1]))^2)<sum((new-c(rv$xcoord[2],rv$ycoord[2]))^2)) {
#sostituisce il primo
rv$xcoord[1]=input$plot_click$x
rv$ycoord[1]=input$plot_click$y
} else {
#sostituisce il secondo
rv$xcoord[2]=input$plot_click$x
rv$ycoord[2]=input$plot_click$y
}
}
if (length(rv$xcoord)>1){
m=(rv$ycoord[2]-rv$ycoord[1])/(rv$xcoord[2]-rv$xcoord[1])
q=rv$ycoord[1]-m*rv$xcoord[1]
currsumsq=sum((rv$y-m*rv$x-q)^2)
if (length(rv$sumsq)>0){
rv$testo2=""
temp=rv$sumsq
lastsumsq=temp[length(temp)]
if (currsumsq<=lastsumsq){
temp=c(temp,currsumsq)
rv$sumsq=temp
rv$currsumsq=NA
rv$currbest=c(q,m)
rv$testo1=paste0("You have improved your guess: the new line has residual sum of squares ",
signif(currsumsq,4),
", your previous guess had residual sum of squares ",
signif(lastsumsq,4),
", the line of best fit has sum of squares ",signif(rv$minsumsq,4),". Can you do better?")
insertUI(selector = "#titolo",
where = "afterEnd",
ui = tags$audio(src = paste0("sounds/suonorr.wav"),
type = "audio/wav",
autoplay = TRUE, controls = "controls"
, style="display:none;"))
} else {
rv$currsumsq=currsumsq
rv$testo1=paste0("You have worsened your guess: the new line has residual sum of squares ",signif(currsumsq,4),", your previous guess had residual sum of squares ",signif(lastsumsq,4)," and the line of best fit has sum of squares ",signif(rv$minsumsq,4),", try again.")
insertUI(selector = "#titolo",
where = "afterEnd",
ui = tags$audio(src = paste0("sounds/suonowr.wav"),
type = "audio/wav",
autoplay = TRUE, controls = "controls"
, style="display:none;"))
}
} else {
rv$sumsq=currsumsq
rv$currbest=c(q,m)
rv$testo1=paste0("Great! You have your first guess, your line has residual sum of squares ",signif(currsumsq,4),
" the line of best fit has sum of squares ",signif(rv$minsumsq,4)," (see the plot on the right).")
rv$testo2=paste0("You can try to improve your guess, by clicking on the graph you will move the nearest point and change the line accordingly.")
}
}
})
observeEvent(rv$show,{
if (rv$show>0) {
rv$testo1=paste0("Your best guess has residual sum of squares ",signif(min(rv$sumsq),4),
" the line of best fit, plotted in green, has sum of squares ",signif(rv$minsumsq,4))
rv$testo2="Press New to try again."
}
})
output$grafico=renderPlot({
req(rv$x*rv$y)
par(mar=c(5,4.5,1,1))
plot(rv$x,rv$y,xlab="x",ylab="y",las=1)
if (length(rv$xcoord)>0){
points(rv$xcoord,rv$ycoord,col="darkred",cex=2,pch=20)
}
if (!is.na(rv$currbest[1])) abline(rv$currbest,lwd=2)
if ((length(rv$xcoord)>1)&!is.na(rv$currsumsq)){
m=(rv$ycoord[2]-rv$ycoord[1])/(rv$xcoord[2]-rv$xcoord[1])
q=rv$ycoord[1]-m*rv$xcoord[1]
abline(q,m,col="darkred",lwd=2)
}
if (rv$show!=0){
abline(coef(rv$fit),col="darkgreen",lwd=2)
}
})
observeEvent(input$scarica,{
dati=data.frame(y=rv$ycoord,x=rv$xcoord)
.GlobalEnv$data.LMboard=dati
#save(results,file=paste0(wd,"/results.Rdata"))
})
output$testo1=renderText(
paste(rv$testo1)
)
output$testo2=renderText(
paste(rv$testo2)
)
output$graficossq0=renderPlot({
req(length(rv$sumsq)>0)
par(mar=c(5,4.5,1,1))
plot(1:pmax(5,length(rv$sumsq)+1),rep(rv$minsumsq,pmax(5,length(rv$sumsq)+1)),type="n",
ylim=c(rv$minsumsq,max(c(max(rv$sumsq),rv$currsumsq),na.rm=TRUE)), #max(rv$sumsq)),
xlab="",ylab="Residual sum of squares",xaxt="n")
points(1:length(rv$sumsq),rv$sumsq,pch=20,cex=2)
lines(1:length(rv$sumsq),rv$sumsq,lwd=2)
if (!is.na(rv$currsumsq)){
points((length(rv$sumsq)+1),rv$currsumsq,col="darkred",pch=20,cex=2)
lines(length(rv$sumsq)+c(0,1),c(rv$sumsq[length(rv$sumsq)],rv$currsumsq),col="darkred",lwd=2)
}
abline(h=rv$minsumsq,col="darkgreen",lwd=2)
})
output$graficossq=renderPlot({
req(length(rv$sumsq)>0)
par(mar=c(5,1,1,4))
miny=rv$minsumsq-0.1*(max(rv$sumsq)-rv$minsumsq)
maxy=max(c(max(rv$sumsq)+0.5*(max(rv$sumsq)-rv$minsumsq),rv$currsumsq),na.rm=TRUE)
assex=signif(c(miny,rv$minsumsq,rv$sumsq,maxy),4)
plot(0,0,type="n",
ylim=c(miny,maxy),xlim=c(-0.5,0.5),xaxs="i",
xlab="",ylab="Residual sum of squares",xaxt="n",yaxt="n",las=1,bty="n")
rect(-0.5,miny,0.5,maxy)
rect(-0.5,rv$minsumsq,0.5,rv$sumsq[length(rv$sumsq)],col=gray(0.5))
rect(-0.5,miny,0.5,rv$minsumsq,col="darkgreen")
if (!is.na(rv$currsumsq)){
rect(-0.5,rv$sumsq[length(rv$sumsq)],0.5,rv$currsumsq,col="darkred")
#abline(h=rv$currsumsq,col="darkred",lwd=2)
}
axis(4,at=assex,las=1)
abline(h=rv$minsumsq,col="darkgreen",lwd=2)
})
}
shinyApp(ui = ui, server = server)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.