Running a logistic model in R involves writing R code that does the
following
There’s a lot of code to write
require(MASS);
require(pscl);
require(equatiomatic)
require(textutils)
#Builds a logistic model
Logistic1= glm(Survived ~ Class+Sex+Age, weights=, family =binomial(link='logit'), na.action=na.exclude,
data=titanic.raw)
#Display theoretical model equation and coefficients
#Display theoretical model
reg_formula = equatiomatic::extract_eq(Logistic1, raw_tex = FALSE,
wrap = TRUE, intercept = "alpha", ital_vars = FALSE)
BSkyFormat(reg_formula)
#Display coefficients
reg_equation = equatiomatic::extract_eq(Logistic1, use_coefs = TRUE,
wrap = TRUE,ital_vars = FALSE, coef_digits = BSkyGetDecimalDigitSetting() )
BSkyFormat(reg_equation)
#Summarizing the model
BSky_Logistic = summary(Logistic1)
BSkyFormat(BSky_Logistic, singleTableOutputHeader="Model Summary")
#Analysis of variance
BSky_anova = anova(Logistic1, test="Chisq")
BSkyFormat(as.data.frame(BSky_anova),singleTableOutputHeader="Analysis of Deviance Table")
BSkyFormat(attr(BSky_anova, "heading"))
#McFadden R2
BSkyFormat( pR2(Logistic1) ,singleTableOutputHeader="McFadden R2")
#odds ratio and 95% confidence interval
BSkyFormat(exp(cbind(OR=coef(Logistic1), confint.glm(Logistic1,level=0.95))),singleTableOutputHeader="Odds ratio(OR) and 95% Confidence interval ")
The Output is not pretty
Use a point and click GUI instead of writing R code for popular analysis
See the nicely formatted output in tables that you can copy and paste into Microsoft Word, Excel…
Not only can you inspect the R code from the output, but you can edit and execute it as well.
require(MASS);
require(pscl);
require(equatiomatic)
require(textutils)
#Builds a logistic model
Logistic1= glm(Survived ~ Class+Sex+Age, weights=, family =binomial(link='logit'), na.action=na.exclude,
data=titanic.raw)
#Display theoretical model equation and coefficients
#Display theoretical model
reg_formula = equatiomatic::extract_eq(Logistic1, raw_tex = FALSE,
wrap = TRUE, intercept = "alpha", ital_vars = FALSE)
BSkyFormat(reg_formula)
#Display coefficients
reg_equation = equatiomatic::extract_eq(Logistic1, use_coefs = TRUE,
wrap = TRUE,ital_vars = FALSE, coef_digits = BSkyGetDecimalDigitSetting() )
BSkyFormat(reg_equation)
#Summarizing the model
BSky_Logistic = summary(Logistic1)
BSkyFormat(BSky_Logistic, singleTableOutputHeader="Model Summary")
#Analysis of variance
BSky_anova = anova(Logistic1, test="Chisq")
BSkyFormat(as.data.frame(BSky_anova),singleTableOutputHeader="Analysis of Deviance Table")
BSkyFormat(attr(BSky_anova, "heading"))
#McFadden R2
BSkyFormat( pR2(Logistic1) ,singleTableOutputHeader="McFadden R2")
#odds ratio and 95% confidence interval
BSkyFormat(exp(cbind(OR=coef(Logistic1), confint.glm(Logistic1,level=0.95))),singleTableOutputHeader="Odds ratio(OR) and 95% Confidence interval ")
The parameters that get substituted based on user entry are in
BOLD text in the code block below require(MASS);
require(pscl);
require(equatiomatic)
require(textutils)
#Builds a logistic model
Logistic1=
glm(Survived ~ Class+Sex+Age, weights=, family
=binomial(link=‘logit’), na.action=na.exclude, data=titanic.raw)
#Display theoretical model equation and coefficients
#Display
theoretical model
reg_formula = equatiomatic::extract_eq(Logistic1,
raw_tex = FALSE, wrap = TRUE, intercept = “alpha”, ital_vars = FALSE)
BSkyFormat(reg_formula)
#Display coefficients
reg_equation
= equatiomatic::extract_eq(Logistic1, use_coefs = TRUE, wrap =
TRUE,ital_vars = FALSE, coef_digits = BSkyGetDecimalDigitSetting() )
BSkyFormat(reg_equation)
#Summarizing the model
BSky_Logistic =
summary(Logistic1)
BSkyFormat(BSky_Logistic,
singleTableOutputHeader=“Model Summary”)
#Analysis of variance
BSky_anova = anova(Logistic1, test=“Chisq”)
BSkyFormat(as.data.frame(BSky_anova),singleTableOutputHeader=“Analysis
of Deviance Table”)
BSkyFormat(attr(BSky_anova, “heading”))
#McFadden R2
BSkyFormat( pR2(Logistic1)
,singleTableOutputHeader=“McFadden R2”)
#odds ratio and 95%
confidence interval
BSkyFormat(exp(cbind(OR=coef(Logistic1),
confint.glm(Logistic1,level=0.95))),singleTableOutputHeader=“Odds
ratio(OR) and 95% Confidence interval”)
NOTE: See how the string that gets substituted for the dependent variables in logistic regression i.e. Class+Sex+Age is different from the string that gets substituted for the dependent variables in Random Forest i.e. c(‘Class’,‘Sex’,‘Age’) This is important as different R functions will want dependent variables specified in different formats. In a vast majority of the cases, the extraction property associated with the user interface component e.g. variable list, textbox etc described below will give you the flexibility to control how the string gets substituted to meet the needs of the R function you want to execute.
BSkyFormat is a function provided with the BlueSky Statistics application and available in the BlueSky package that generates nicely formatted output for R objects of the following classes. data.frame matrix table ftable List xtabs htest glm lm by lm Anova summary.glm numSummary tapply summary.lm summary.multinorm multinorm polr summary.polr vectors Type help(BSkyFormat) in the BlueSky Statistics R Syntax editor to see additional details and parameters that can be passed to BSkyFormat
require(MASS);
require(pscl);
require(equatiomatic)
require(textutils)
#Builds a logistic model
Logistic1=
glm(Survived ~ Class+Sex+Age, weights=, family =binomial(link=‘logit’),
na.action=na.exclude, data=titanic.raw)
#Display theoretical model
equation and coefficients
#Display theoretical model
reg_formula
= equatiomatic::extract_eq(Logistic1, raw_tex = FALSE, wrap = TRUE,
intercept = “alpha”, ital_vars = FALSE)
BSkyFormat(reg_formula)
#Display coefficients
reg_equation = equatiomatic::extract_eq(Logistic1, use_coefs = TRUE,
wrap = TRUE,ital_vars = FALSE, coef_digits =
BSkyGetDecimalDigitSetting() )
BSkyFormat(reg_equation)
#Summarizing the model
BSky_Logistic = summary(Logistic1)
BSkyFormat(BSky_Logistic,
singleTableOutputHeader=“Model Summary”)
#Analysis of variance
BSky_anova = anova(Logistic1, test=“Chisq”)
BSkyFormat(as.data.frame(BSky_anova),singleTableOutputHeader=“Analysis
of Deviance Table”)
BSkyFormat(attr(BSky_anova, “heading”))
#McFadden R2
BSkyFormat( pR2(Logistic1)
,singleTableOutputHeader=“McFadden R2”)
#odds ratio and 95%
confidence interval
BSkyFormat(exp(cbind(OR=coef(Logistic1),
confint.glm(Logistic1,level=0.95))),singleTableOutputHeader=“Odds
ratio(OR) and 95% Confidence interval”)
To extend BlueSky Statistics, you create new dialogs. The dialog is basically javascript code that specifies the following
A dialog has the following properties
id: "sampleDialog1"
label: localization.en.title
splitProcessing:false
RCode: `
paste(c({{selected.independent | safe}}))
print("{{selected.inputControl | safe}}")
`
Single column All user interface controls are presented in a single column, one below each other
Two column All user interface controls are presented in one of 2 columns, one below each other
E.g. for single column
modalType: "one",
modalType: "two",
NOTE: The head, bottom sections are optional.
The items property
is only used when modalType: “one”
Header: Optionally place controls in a header
Bottom: Optionally place controls below the source variable list
E.g.To place the control that captures the name of the model on the top of the dialog
head: [objects.modelname.el.content]
left: [objects.content_var.el.content]
right: [objects.modelname.el.content, objects.dependent.el.content, objects.independent.el.content]
bottom: [objects.modelname.el.content]
items: [objects.shape1.el.content, objects.shape2.el.content,
objects.plotdenfun.el.content]
const content = {
left: [objects.content_var.el.content],
right: [objects.modelname.el.content, objects.dependent.el.content, objects.independent.el.content, objects.generateplotchk.el.content, objects.destination2.el.content]
};
nav: { name: localization.en.navigation}
nav: { icon: "icon-logistic_white_comp"}
const content = {
left: [objects.content_var.el.content],
right: [objects.modelname.el.content, objects.dependent.el.content, objects.independent.el.content, objects.generateplotchk.el.content, objects.destination2.el.content],
nav: {
name: localization.en.navigation,
icon: "icon-logistic_white_comp",
modal: config.id
}
};
nav: {datasetRequired:true}
help: {
title: "Enter a title here",
r_help: "help(glm, package=‘stats’)"
}
,
body: ‘
<b>Description</b></br>
Builds a binary logistic regression model.... <br/>’
help: {
r_help: "help(glm, package=‘stats’)"
}
Study sample dialog Sample 1.js in the development folder in the install directory of the BlueSky Statistics application.
Perform the following Exercises Exercise 1 Exercise 1a Exercise 1b
action: "move"
action: "copy"
content_var: {
el: new srcVariableList(config, {
action: "move"
})
},
action: "move"
action: "copy"
dataset_var: {
el: new srcDatasetList(config, {
action: "move"
})
},
no: unique id (each control within a dialog must have a unique id). This unique id is used in the R code to substitute the control content
no: "independent"
label: String displayed above the variable control
label:“Independent variable(s)"
required: Optionally force the user to enter a value in the variable control. Dialog will not execute unless a user specifies a value. Default is false.
required:false
allowedSrcCtrls: Optionally specify the source variable from which variables can be dragged and dropped (or moved) to this control. NOTE: vice versa i.e. having a property on a source variable that specifies the destination controls from which variables can be dropped from is not necessary as the drag and drop (or move) already handles this. You cannot drag and drop or move a variable from a destination variable list to a source variable list that it did not originally contain this variable
allowedSrcCtrls: ["semmultiGrpSrcVars"]
filter: Control the types of variables this control can contain
filter: "Numeric|Date|Logical|Ordinal|Nominal|Scale"
filter: "Numeric|Scale"
filter: "Numeric|Nominal"
filter: "Numeric|Ordinal"
filter: "Numeric|Logical"
filter: "String"
extraction: Control how the variable entered gets substituted in the R code
extraction: "NoPrefix|UseComma"
extraction: "Prefix|UseComma"
extraction: "CustomFormat"
dependent: {
el: new dstVariable(config, {
label: localization.en.dependent,
no: "dependent",
filter: "String|Numeric|Logical|Ordinal|Nominal",
extraction: "NoPrefix|UseComma",
required: true,
}),
},
{{selected.dependent | safe}}
Rcode:`{{selected.modelname | safe}}= glm({{selected.dependent | safe}} ~ {{selected.independent | safe}}….`
no: "in1"
label: "Select the 1st Dataset"
required:false
filter: "Dataset"
extraction: "NoPrefix|UseComma"
extraction: "NoPrefix|UseComma|Enclosed"
in1: {
el: new dstVariable(config, {
label: localization.en.in1,
no: "in1",
filter: "Dataset",
extraction: "UseComma|Enclosed",
required: true,
})
},
{{selected.in1 | safe}}
Rcode:`paste( "{{selected.mergetype | safe}}","(",{{selected.in1 | safe}},",",{{selected.in2 | safe}},",","by = c(",by.text,"),","{{selected.suffix | safe}}",")")`
no: "independent"
label:"Independent variable(s)"
required:false
filter: "Numeric|Date|Logical|Ordinal|Nominal|Scale"
filter: "Numeric|Scale"
filter: "Numeric|Nominal"
filter: "Numeric|Ordinal"
filter: "Numeric|Logical"
filter: "String"
extraction: "NoPrefix|UseComma"
extraction: "NoPrefix|UsePlus"
extraction: "Prefix|UseComma"
extraction: "CustomFormat"
wrapped: 'weight=c(%val%),\n'
independent: {
el: new dstVariableList(config,{
label: localization.en.independent,
no: "independent",
required: true,
filter:"String|Numeric|Logical|Ordinal|Nominal|Scale",
extraction: "NoPrefix|UsePlus",
})
},
{{selected.independent | safe}}
Rcode:`{{selected.modelname | safe}}= glm({{selected.dependent | safe}} ~ {{selected.independent | safe}}….`
Drag and Drop/Move/ Copy one or more Datasets from the Source Dataset List to the Destination Dataset List Control
Optionally force the user to select a Dataset (Dialog will not execute unless the user adds a Dataset)
no: "in1"
label: "Select the 1st Dataset"
required:false
filter: "Dataset" allows only datasets
extraction: "NoPrefix|UseComma"
extraction: "NoPrefix|UseComma|Enclosed"
in1: {
el: new dstVariableList(config,{
label: localization.en.in1,
no: "in1",
filter: "Dataset",
extraction: "UseComma|Enclosed",
required: true.
})
},
{{selected.in1 | safe}}
Rcode:`paste( "{{selected.mergetype | safe}}","(",{{selected.in1 | safe}},",",{{selected.in2 | safe}},",","by = c(",by.text,"),","{{selected.suffix | safe}}",")")`
no: 'modelname'
label: "Enter model name"
placeholder: "Logistic1"
required:false
extraction: "TextAsIs"
extraction: "CreateArray"
extraction: "Prefix"
extraction: "Prefix|Enclosed"
extraction: "CreateArray|RemoveSpaces“
type: "character"
type: "numeric"
type: "onlyCharacter",
enforceRobjectRules: true
enforceRobjectRules: false
allowSpacesNew: true
allowSpacesNew: false
allow_spaces:true
allow_spaces:true
type: "numeric"
allow_spaces:true
type: "character"
value: Optionally display a value in the TextBox when its displayed
value: "Logistic1"
overwrite: If a user enters the name of a dataset or variable name in the textbox, you can optionally prompt the user to overwrite the dataset or variable (in the active dataset) if it exists
overwrite: "dataset",
overwrite: "variable",
style: Optionally customize left, top and bottom margins to improve layout. We use a relative scale from 1-5
style="ml-1 mt-1 mb-3"
style="ml-2"
style="mb-2"
ml: Optionally customize left margin to improve layout. We use a relative scale from 1-5
ml:2
Note: ml only works when a textbox is below a checkbox, it does not work when the textbox is the 1st control
wrapped: Allows you to wrap the results of the control within another string. For example, just say you want to pass the parameter weights = c(“variable name”) to a function but only when the weights value was specified. %val% represents the value of the control.
wrapped: 'weight=c(%val%),\n'
width: Specify the RELATIVE width of the textbox.This allows you to control whether the textbox occupies 25%, 50%, 75% or 100% of the available width. These are the ONLY options supported, you cannot specify any arbitrary width. The following options are available “w-25”, “w-50”, “w-75”, “w-100” with “w-75” being the default.
width: "w-25"
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
required: true,
type: "character",
enforceRobjectRules:true,
extraction: "TextAsIs",
value: "BSkyMANOVAModel",
overwrite: "dataset"
})},
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
type: "numeric",
extraction: "TextAsIs",
value: "BSkyMANOVAModel",
overwrite: "dataset"
})
},
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
required: true,
type: "character",
enforceRobjectRules:false,
extraction: "TextAsIs",
value: "BSkyMANOVAModel",
overwrite: "dataset"
})
},
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
required: true,
type: "character",
enforceRobjectRules:false,
extraction: "TextAsIs",
value: "BSkyMANOVAModel",
allowSpacesNew: false,
overwrite: "dataset"
})
},
*Force only characters/strings not numbers (type: “onlyCharacter”), note you will not be allowed to enter spaces or numbers. The reason is we check if the value entered is a numeric and trigger an error, since we set the legacy flag allow_spaces to false for legacy compatibility, we will make sure R object rules are applied. You will not be allowed to enter spaces or numbers
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
type: "onlyCharacter",
extraction: "TextAsIs",
value: "BSkyMANOVAModel",
overwrite: "dataset"
})
},
*Sample code for entering only characters (no numbers allowed) (type: “onlyCharacter”) without spaces (allowSpacesNew: false)
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
type: "onlyCharacter",
allowSpacesNew: false,
extraction: "TextAsIs",
value: "BSkyMANOVAModel",
overwrite: "dataset"
})
},
newdatasetname: {
el: new input(config, {
no: 'newdatasetname',
label: localization.en.newdatasetname,
placeholder: "",
extraction: "TextAsIs",
type: "character",
value: "",
ml: 4,
width:"w-25",
})
},
newdatasetname: {
el: new input(config, {
no: 'newdatasetname',
label: localization.en.newdatasetname,
placeholder: "",
extraction: "TextAsIs",
type: "character",
overwrite: "dataset",
value: "",
ml: 4,
width:"w-100",
})
},
newdatasetname: {
el: new input(config, {
no: 'specify_a_title',
label: localization.en.specify_a_title,
placeholder: "Chart title",
allow_spaces: true,
extraction: "TextAsIs"
})
},
newdatasetname: {
el: new input(config, {
no: 'ci',
allow_spaces: true,
type: "numeric",
label: localization.en.ci,
placeholder: "0.995",
extraction: "TextAsIs"
})
},
{{selected.modelname | safe}}
Rcode:`{{selected.modelname | safe}} = glm({{selected.dependent | safe}} ~…`
no: "generateplotchk"
label:"Plot residuals vs fitted, normal Q-Q, scale-location…"
required:false
extraction: "Boolean"
extraction: "TextAsIs"
true_value: "This is true"
false_value: "This is false"
dependant_objects: ["input_no_value", "input_value"]
style="ml-1 mt-1 mb-3"
style="ml-2"
style="mb-2"
bs_type: “valuebox”
Summary: {
el: new checkbox(config, {
label: localization.en.Summary,
no: "chk5",
extraction: "Boolean"
})
},
showResultsinOutput: {
el: new checkbox(config, {
label: localization.en.showResultsinOutput,
no: "showResultsinOutput",
bs_type: "valuebox",
extraction: "TextAsIs ",
true_value: "TRUE",
false_value: "FALSE",
})
},
distinct: {
el: new checkbox(config, {
label: localization.en.distinct,
no: "distinct",
style: "mt-2"
bs_type: "valuebox",
extraction: "TextAsIs",
true_value: "%>%\n\tdistinct",
false_value: " ",
})
},
distinct: {
el: new checkbox(config, {
label: localization.en.distinct,
no: "distinct",
style: "mt-2"
bs_type: "valuebox",
extraction: "TextAsIs",
true_value: "%>%\n\tdistinct",
false_value: " ",
newline: true,
})
},
storeClusterInDataset: {
el: new checkbox(config, {
label: localization.en.stroreClusterInDataset,
no: "storeclusterInDataset",
required: true,
dependent_objects: ["variablename"],
extraction: "Boolean"
})
},
{{selected. chkbox1 | safe}}
Rcode:`correct={{selected.chkbox1 | safe}}`
label: "Function to compute the center of each group"
h: 5
h: 3
style="ml-1 mt-1 mb-3"
style="ml-2"
style="mb-2"
label1: {
el: new labelVar(config, {
label: localization.en.label1,
style: "mt-3",
h:5
})
},
label: "Subsetting criteria is applied against each row, see examples below. \n1: Select rows"
h:5
h:3
label12: {
el: new preVar(config, {
no: "label12",
label: localization.en.label12,
h:6
})
},
no: 'testStatistic'
label: "Test statistic"
multiple: false
multiple: true
required:false
extraction: "NoPrefix|UseComma"
options: ["Hotelling-Lawley", "Pillai", "Roy", "Wilks"]
default: "Wilks"
testStatistic: {
el: new comboBox(config, {
no: "testStatistic",
label: localization.en.testStatistic,
multiple: false,
extraction: "NoPrefix|UseComma",
options: ["Hotelling-Lawley", "Pillai", "Roy", "Wilks"],
default: "Wilks"
})
},
Reference the value of the no property of the control, see the example below the value of the no property is “testStatistic”
{{selected.testStatistic | safe}}
Rcode:`BSkyMANOVASummary <- summary({{selected.modelname | safe}}, test = c("{{selected.testStatistic | safe}}"))`
no: 'family'
nochild: 'combokid'
label: “Select a family and link function"
multiple: false
multiple: true
extraction: "NoPrefix|UseComma"
options: [ { "name": "gaussian", "value": ["identity", "inverse", "log"] }]
family: {
el: new comboBoxWithChilderen(config, {
no: 'family',
nochild: 'combokid',
label: localization.en.family,
multiple: false,
extraction "NoPrefix|UseComma",
options: [
{ "name": "gaussian", "value": ["identity", "inverse", "log"] },
{ "name": "binomial", "value": ["logit", "probit", "cauchit","log","cloglog"] },
{ "name": "poisson", "value": [ "log","identity", "sqrt"] },
{ "name": "Gamma", "value": ["inverse","identity", "log"] },
{ "name": "inverse.gaussian", "value": ["1/mu^2","identity", "inverse", "log" ] },
{ "name": "quasi", "value": [ "logit","probit","cloglog","identity","inverse", "log", "1/mu^2","sqrt" ] },
{ "name": "quasibinomial", "value": ["logit", "probit", "cloglog"] },
{ "name": "quasipoisson", "value": ["log","identity", "sqrt"] },
]
})
},
Reference the value of the no property of the control, see the example below the value of the no property is “family” and value of the nochild property is “combokid”
{{selected.family| safe}}
{{selected.combokid| safe}}
Rcode:`…family ={{selected.family | safe}}(link="{{selected.combokid | safe}}…`
no: 'selectAPackage'
label: "Select A Package",
required:false
extraction: "NoPrefix|UseComma"
options: ["car", "ggplot2", "gplots", "psych"]
default: "car"
onselect_r: {selectADataset: "BSkyGetDatasetNameTitle(package = c('{{value}}'))"
NOTE: passing the selected value to the R function is optional.
{{value}} above contains the selected value. selectAPackage: {
el: new selectVar(config, {
no: 'selectAPackage',
label: "Select A Package",
multiple: false,
extraction: "NoPrefix|UseComma",
options: ["car", "ggplot2", "gplots", "psych"],
default: ""
})
},
Reference the value of the no property of the control, see the example below the value of the no property is “selectAPackage”
{{selected.selectAPackage | safe}}
Rcode:`print("The name of the package selected is : {{selected.selectAPackage | safe}}")
no: unique id (each control within a dialog must have a unique id) This unique id is used in the R code to substitute the control value
no: "box1"
label: String displayed above the inputSpinner control
label: "Confidence Interval"
min: The minimum value
min:0
max: The maximum value
max:1
step: The amount the value displayed increments/decrements when the up arrow/down arrow is clicked
value: The initial value displayed when the control is rendered
value:0.95
extraction: Control how the entered value gets substituted in the R code
extraction: "NoPrefix|UseComma"
box1: {
el: new inputSpinner(config, {
no: 'box1',
label: localization.en.txtbox1,
min: 0,
max: 1,
step: 0.01,
value: 0.95,
extraction: "NoPrefix|UseComma"
})
},
{{selected.box1 | safe}}
Rcode:`…conf.level={{selected.box1 | safe}}`
no: unique id (each control within a dialog must have a unique id) This unique id is used in the R code to substitute the control value
no: "cilevel"
label: String displayed above the Advanced Slider control
label: "Confidence Interval"
min: The minimum value
min:0
max: The maximum value
max:1
step: The amount the value displayed increments/decrements when the top/bttom arrows are clicked with the slider ball is clicked
value: The initial value displayed when the control is rendered
value:0.95
extraction: Control how the entered value gets substituted in the R code
extraction: "NoPrefix|UseComma"
cilevel: {
el: new advancedSlider(config,{
no: 'cilevel',
label: localization.en.cilevel,
min: 0,
max: 1,
step: 0.05,
value: 0.95,
extraction: "NoPrefix|UseComma"
})
},
{{selected.cilevel | safe}}
`Rcode:`…conf.level={{selected.cilevel | safe}}`
no: "formula"
required:false
formulaBuilder: {
el: new formulaBuilder(config, {
no: "formula",
required: true,
})
},
{{selected.formula | safe}}
Rcode:`…conf.level={{selected.formula| safe}}`
no: "timeZoneOptions"
name: "Advanced"
layout: "two"
left: [
objects.mediationSrcCtrl.el,
],
right: [
objects.mediationDestCtrl.el
],
layout: "three"
top: [objects.label1.el,],
left: [
objects.modelTerms.el,
],
center: [
objects.modelTerms1.el,
],
right: [
objects.modelTermsDst.el,
],
layout: "four",
top: [objects.label5.el],
left: [
objects.label4.el,
objects.addFitMeasures.el,
objects.mardiaSkew.el,
objects.mardiaKurt.el,
objects.label6.el,
objects.r2squareNone.el,
objects.r2squareEndo.el
],
center: [
objects.label5.el,
objects.observed.el,
objects.modelImplied.el,
objects.residual.el,
objects.residualCovHeatmap.el,
objects.observedCorr.el,
],
right: [
objects.label8.el,
objects.modIndices.el,
objects.highLowIndices.el,
objects.threshold.el
],
layout: "five",
top: [objects.label5.el],
left: [
objects.label4.el,
objects.addFitMeasures.el,
objects.mardiaSkew.el,
objects.mardiaKurt.el,
objects.label6.el,
objects.r2squareNone.el,
objects.r2squareEndo.el
],
right: [
objects.label8.el,
objects.modIndices.el,
objects.highLowIndices.el,
objects.threshold.el
],
bottom: [objects.label7.el],
layout: "six",
top: [objects.label5.el],
left: [
objects.label4.el,
objects.addFitMeasures.el,
objects.mardiaSkew.el,
objects.mardiaKurt.el,
objects.label6.el,
objects.r2squareNone.el,
objects.r2squareEndo.el
],
center: [
objects.label5.el,
objects.observed.el,
objects.modelImplied.el,
objects.residual.el,
objects.residualCovHeatmap.el,
objects.observedCorr.el,
],
right: [
objects.label8.el,
objects.modIndices.el,
objects.highLowIndices.el,
objects.threshold.el
],
bottom: [objects.label7.el],
var timeZoneOptions = {
el: new optionsVar(config, {
no: "timeZoneOptions",
name: "Advanced",
content: [
objects.TimeZone.el,
]
})
},
TimeZone is a ComboBox Control within objects
no: "importResp"
label: "Select a file to open"
required:true
extraction: "TextAsIs"
importResp: {
el: new fileOpenControl(config,
{
no: "importResp",
label: "Select a file to open",
extraction: "TextAsIs"
})}
}
{{selected.importResp | safe}}
Rcode:`base::open({{selected.modelSelection | safe}}, file = "{{selected.importResp | safe}}")`
no: "importResp"
label: "Select a new/existing file to save a model to"
required:true
extraction: "TextAsIs"
importResp: {
el: new fileSaveControl(config,
{
no: "importResp",
label: "Select a file to save a model to",
extraction: "TextAsIs",
required: "true"
})},
{{selected.importResp | safe}}
Rcode:`base::save({{selected.modelSelection | safe}}, file = "{{selected.importResp | safe}}")`
Open the dataset you want to score/make predictions for.
Select a model you have built.
We run diagnostics tests to validate whether the independent variables used to build the selected model are present in the dataset to be scored. The results of the diagnostic tests are displayed on the dialog itself. You will see SUCCESS or ERROR with additional information. We also display the dependent variable name and ask the user to specify a prefix for the new variable(s) created with the scores and predicted probabilities when relevant. The scores will be saved to a new variable name with the prefix specified appended to the original dependent variable used to create the model.
If the independent variables required to build the model are not present in the dataset to be scored. We display an error. You will not be able to score the dataset.
You must save the dependent variable in an attribute of the model created. The name of that attribute must be depvar. The format of the value stored in the attribute must be “‘Name of the dependent variable’”
You must save the independent variables in an attribute of the model created. The name of that attribute must be indepvar. The format of the value must be as below
c("independentVariable1", "independentVariable2", "independentVariable3", "independentVariable4", ...)
Extracting the dependent and independent variables from the models you create is not always straight forward, see cases below from simple to more complex
The R code for the model fitting function takes a character vector as the dependent and independent variable
mlp( x=c('Sepal.Length','Sepal.Width','Petal.Length','Petal.Width'), y= c('Species')), size = c(5), maxit = 100,
learnFunc = "Std_Backpropagation" )
As both the dependent and independent variables are character vectors, setting the required attribute values are easy. See sample code below.
#Setting attributes to support scoring
attr(.GlobalEnv\${{selected.model | safe}},"depvar")="{{selected.dependentvar | safe}}"
attr(.GlobalEnv\${{selected.model | safe}},"indepvar")="{{selected.independentvars | safe}}"
attr(.GlobalEnv\${{selected.model | safe}},"classDepVar")= class({{dataset.name}}[, c({{selected.dependentvar | safe}})])
attr(.GlobalEnv\${{selected.model | safe}},"depVarSample")= sample({{dataset.name}}[, c({{selected.dependentvar | safe}})], size = 2, replace = TRUE)
See R code generated by Model Fitting>Neural
nets>Multi-layer perceptron for more details.
The R code for the model is expressed as a formula, for example see below
neuralnet( formula=medv ~ crim+zn+indus+chas+nox+rm+age+dis+rad+tax+ptratio+black+lstat, data = Boston_scaled, hidden = c(5),...)
This means the base form is dependentVariable ~ independentVariable1 + independentVariable2 + independentVariable3 … The independent variables need to be converted from the format independentVariable1 + independentVariable2 + independentVariable3 to c(“independentVariable1”, “independentVariable2”, “independentVariable3”) The sample code below will do this conversion
attr(.GlobalEnv\${{selected.model | safe}},"depvar")="'{{selected.dependentvar | safe }}'"
attr(.GlobalEnv\${{selected.model | safe}},"indepvar")=paste(stringr::str_split("{{selected.independentvars}}",fixed("+")),sep=",", collapse="")
For further details, see the R code generated by the dialog Model Fitting>Neuralnets>Neuralnets
The model formula may be manually created with interactions, polynomial terms, splines… for example
QuantRegModel1 <- rq(mpg ~ hp + drat + I(wt^1) + I(wt^2) + splines::bs(disp, df =5) , tau = 0.5....)
The independent variables need to be extracted from the formula must be in the format see below
c("hp", "drat", "wt", "disp")
The sample code that will do this conversion is below
BSkyFormula = mpg ~ hp + drat + I(wt^1) + I(wt^2) + splines::bs(disp, df =5)
attr(.GlobalEnv\${{selected.modelname | safe}},"depvar") = "{{selected.depvar | safe}}"
attr(.GlobalEnv\${{selected.modelname | safe}},"indepvar") = paste ("'", paste (base::all.vars(BSkyFormula[-2]), collapse="','"), "'", sep="")
For further details, see the R code generated by the dialog Model Fitting > Quantile Regression
The R code that generates the model is in the form
randomForest(x = mtcars[,c('disp','hp','drat','wt','qsec','vs')], y=mtcars$cyl...)
Here the independent variable format is fine but the dependent variable needs to be transformed to eliminate the dataset name (mtcars) and the $, see R code below from the Model Fitting > Trees > Random Forest
attr(.GlobalEnv\${{selected.modelname | safe}}, "depvar") = paste ("'", sub(".*\\\\$", "", '{{selected.dependentvar | safe}}'), "'", sep="")
attr(.GlobalEnv\${{selected.modelname | safe}}, "indepvar") ="{{selected.independentvars | safe}}"
attr(.GlobalEnv\${{selected.modelname | safe}}, "classDepVar") = class({{selected.dependentvar | safe}})
attr(.GlobalEnv\${{selected.modelname | safe}}, "depVarSample") = sample({{selected.dependentvar | safe}}, size = 2, replace = TRUE)
You also need to store the class of the dependent variable and take a sample of the dependent variable (of size 2) and store both as attributes of the model created. The sample code is below. This ensures that we create the variable that contains the scores with the correct class and factor levels. Factor levels are also needed for the confusion matrix if that option is selected. See sample code below.
attr(.GlobalEnv\${{selected.model | safe}},"classDepVar")= class({{dataset.name}}[, c("{{selected.dependentvar | safe}}")])
attr(.GlobalEnv\${{selected.model | safe}},"depVarSample")= sample({{dataset.name}}[, c("{{selected.dependentvar | safe}}")], size = 2, replace = TRUE)
By default, the BlueSky Statistics application scores models of
the classes below, if the model fitting dialog you are creating is not
in the list below, you need to contact us at support@blueskystatistics.com and we will have to
update the software to accommodate the new model class
“NaiveBayes”,
“drc”, “nls”, “randomForest”, “lm”, “glm”, “rpart”, “multinom”, “nnet”,
“polr”, “ksvm”, “blasso”, “knn3”, “real_adaboost”, “adaboost”,
“lmerModLmerTest”, “xgb.Booster”, “C5.0”, “BinaryTree”, “lognet”,
“glmnet”, “earth”, “mlp”, “rsnns”, “RandomForest”, “rlm”, “rq”,
“ranger”, “gbm”, “nn”, “coxph”
The BlueSky Statistics application gives you configurable default themes for ggplot graphs. If you are generating dialogs that create ggplot based visualizations, you apply these default themes to ensure consistency with the other graphs created with the application.
This can be done by simply appending {{selected.BSkyThemes | safe}} to the ggplot code generated by your dialog. So if your dialog generates the following ggplot code as below
ggplot({{dataset.name}},aes(x = {{selected.blockVar | safe}},y ={{selected.tvarbox1 | safe}},color = {{selected.tvarbox2 | safe}})) + geom_point() + labs(x = "{{selected.blockVar | safe}}",y = "{{selected.tvarbox1 | safe}}",color = "{{selected.tvarbox2 | safe}}") +geom_smooth(method ="lm",se=TRUE) +ggtitle(paste('Scatter plot of the response variable', c('{{selected.tvarbox1 | safe}}'), 'against the covariate variable' ,c('{{selected.blockVar | safe}}'),'\nusing separate symbols for each level of the factor variable \n(lines should have the same slope)' ,c('{{selected.tvarbox2 | safe}}') )
The new code that gives you the ggplot2 themes set in the application is as below
ggplot({{dataset.name}},aes(x = {{selected.blockVar | safe}},y ={{selected.tvarbox1 | safe}},color = {{selected.tvarbox2 | safe}})) + geom_point() + labs(x = "{{selected.blockVar | safe}}",y = "{{selected.tvarbox1 | safe}}",color = "{{selected.tvarbox2 | safe}}") +geom_smooth(method ="lm",se=TRUE) +ggtitle(paste('Scatter plot of the response variable', c('{{selected.tvarbox1 | safe}}'), 'against the covariate variable' ,c('{{selected.blockVar | safe}}'),'\nusing separate symbols for each level of the factor variable \n(lines should have the same slope)' ,c('{{selected.tvarbox2 | safe}}') ) + {{selected.BSkyThemes | safe}})
All sample dialogs are located in the development folder in the installation directory (Default installation directory is c:\program files\BlueSky Statistics\10 folder)
See section “Turning on Debug mode in the BlueSky Statistics application so you can see errors when installing dialogs” to turn on debug mode so you can see the errors generated.
Follow the steps below
Under the top level hamburger menu ( 3 sandwiched lines) click on Marketplace
If you haven’t done so, select a file folder to save installed dialogs to. We will refer to this folder as the folder containing the marketplace dialogs. This must be a folder on your computer that you have write permissions to. The dialogs you are installing get copied here.
Now choose a top level menu tab where you want your dialog to be installed to. To follow with this exercise, lets select the top level menu tab “Datasets”. This will ensure that the sample dialog will appear in the Datasets tab.
Click the button “Select a Dialog” to Upload a sample dialog by browsing to the development folder in the installation directory (Default installation directory is c:\program files\BlueSky Statistics\10 folder)
Select the dialog file Sample 1.js
Click on the Upload button, this will upload the dialog and make it available in the Datasets menu for installation
On successful upload, the screen will refresh and automatically scroll to the place on the Datasets tab where the newly installed dialog is available for you to install.
Click on the Install button associated with the Sample 1 dialog, this will install the dialog into the top level menu.
Click on Datasets in the top navigation, you will see the new dialog Sample 1 on the far right.
Open a sample dataset and execute the newly installed dialog, it will allow you to build a simple regression model.
The dialog you just installed (Sample 1.js), got copied to the file folder containing the marketplace dialogs. (You can access this folder location by going to the top level hamburger menu ( 3 sandwiched lines) and clicking on Marketplace ). Go ahead browse to the folder and open the dialog in notepad++ or a suitable javascript editor.
Follow the steps below
Change the title of the dialog from “Sample 1” to “Linear Regression” In the “en” object change the value of the “title” property from “Sample 1” to “Linear Regression”. You can find the “en” object by simply searching for en)
Change the text displayed in the top level navigation from “Sample 1” to “Linear Regression” In the “en” object change the value of the “navigation” property from “Sample 1” to “Linear Regression”
Change the title in the Help overlay from “Sample 1” to “Linear Regression” In the “help” object change value of the “title” property from “Sample 1” to “Linear Regression”
Change the placement of the textbox with caption “Enter Model name” from the top of the right column to the bottom of the right column Within the “content” object change right: [objects.modelname.el.content, objects.dependent.el.content, objects.independent.el.content, objects.weights.el.content], to right: [objects.dependent.el.content, objects.independent.el.content, objects.weights.el.content, objects.modelname.el.content ],
Change the label of the weights control Within the en object change the value of the “weights” property from “Specify a variable with weights” to “Optionally Specify a variable with weights”
Save the changes made to Sample 1.js (to the same file folder you specified in the Marketplace dialog)
Navigate back to the Marketplace (go to the top level hamburger menu ( 3 sandwiched lines) and click on Marketplace), click on the Datasets tab, look for the Sample 1 dialog you just installed (you may need to scroll to the bottom).
Click on the “Reload Dialog” button displayed to the right of the Sample 1 entry. You will see your changes when you relaunch the dialog.
If you see errors, try and correct the errors. If you are unable to correct the errors, look at dialog Sample 1a.js. This file has all the modifications above and you can compare your edits with the edits in Sample 1a.js or alternately copy the contents of the sample 1a.js into Sample 1.js and save the file. Then reload the file as in steps 7 and 8 above.
Relaunch the dialog and note how the textbox that captures the name of the model has moved to the bottom of the right column from the top. Note the changes to the Title of the dialog displayed in the navigation, on the main dialog and the Help overlay (click on the ? icon on the top right of the dialog) as well.
In this exercise we will add a new checkbox input control to the dialog. This will allow you to give the user the option to plot the regression model.
Open Sample 1.js (in notepad++ or any suitable javascript editor) from the file folder you specified for the Marketplace dialogs (You can access this folder location by going to the top level hamburger menu ( 3 sandwiched lines) and clicking on Marketplace )and un-comment the code below to add the checkbox control to the dialog
/* generateplotchk: {
el: new checkbox(config, {
label: localization.en.generateplotchk,
no: "generateplotchk",
style: "mt-2 mb-3",
bs_type: "valuebox",
extraction: "TextAsIs",
true_value: "TRUE",
false_value: "FALSE",
})
},*/
right: [objects.modelname.el.content, objects.dependent.el.content, objects.independent.el.content, objects.generateplotchk.el.content, objects.weights.el.content],
Save Sample 1.js
Navigate back to the Marketplace (go to the top level hamburger menu ( 3 sandwiched lines) and click on Marketplace), click on the Datasets tab, look for the sample dialog (now called Linear Regression dialog as you changed the title above) you just installed (you may need to scroll to the bottom)
Click on the “Reload Dialog” button. You will see your changes when you launch the dialog.
If you see errors, try and correct the errors. If you are unable to correct the errors, look at sample 1b.js. This file has all the modifications above and you can compare your edits with the edits in Sample 1b.js or alternately copy the contents of the Sample 1b.js into Sample 1.js and save the file. Then reload the file as in steps 4 and 5 above.
Open the Sample 1 dialog (now called Linear Regression from the Datasets top level menu)and verify that you see the checkbox to draw the plots.
Note that the plots don’t draw when you select this option. We will write the R code to do this in Exercise 7.
Open Sample 1.js (in notepad++ or any suitable javascript editor) from the file folder containing the marketplace dialogs (You can access this folder location by going to the top level hamburger menu ( 3 sandwiched lines) and clicking on Marketplace).
Change the value of the extraction property of the destination variable list control that contains the independent variables from UsePlus to UseComma. The changed code will look like below
independent: {
el: new dstVariableList(config, {
label: localization.en.independent,
no: "independent",
required: true,
filter: "String|Numeric|Logical|Ordinal|Nominal|Scale",
extraction: "NoPrefix|UseComma",
}), r: ['{{ var | safe}}']
},
Save Sample 1.js
Navigate back to the Marketplace, click on the Datasets tab, look for the sample dialog you installed in the steps above (NOTE: the name is Linear Regression due to the change you made above, you may need to scroll to the bottom to see it).
Click on the “Reload Dialog” button.
If you see errors when you click the “Reload Button” try and correct the errors. If you are unable to correct the errors, look at Sample 1c.js. This file has all the modifications above and you can compare your edits with the edits in Sample 1c.js or alternately copy the contents of the Sample 1c.js into Sample 1.js and save the file. Then reload the file as in steps 4 and 5 above.
Open the Sample 1 (now called Linear Regression from the Datasets tab) dialog and move some independent variables
Display the syntax
Execute the dialog and note the error message due to the fact that the independent variables don’t conform to the format that R expects.
Revert the change made above and save the Sample 1.js and Reload to get the dialog to the original state.
Open Sample 1.js from the file folder containing the marketplace dialogs.
Change the value of the extraction property of the destination variable list control that contains the independent variables from UseComma to UsePlus. The changed code will look like below
independent: {
el: new dstVariableList(config, {
label: localization.en.independent,
no: "independent",
required: true,
filter: "String|Numeric|Logical|Ordinal|Nominal|Scale",
extraction: "NoPrefix|UsePlus",
}), r: ['{{ var | safe}}']
},
modelname: {
el: new input(config, {
no: 'modelname',
label: localization.en.modelname,
placeholder: "",
required: true,
type: "character",
extraction: "CreateArray",
value: "LinearRegModel1"
})
},
Save Sample 1.js
Navigate back to the Marketplace, click on the Datasets tab, look for the sample dialog you installed (now called linear regression as you changed the title above)
Click on the “Reload Dialog” button.
If you see errors when you click the “Reload Button” try and correct the errors. If you are unable to correct the errors, look at Sample 1d.js. This file has all the modifications above and you can compare your edits with the edits in Sample 1d.js or alternately copy the contents of the sample 1c.js into sample 1.js and save the file. Then reload the file as in steps 4 and 5 above.
Open the Sample 1 (now called Linear Regression from the Datasets tab) dialog and move some independent variables
Display the syntax, note the incorrect syntax
Execute the dialog and note the error message
Revert the change made in Exercise 4 and Exercise 5 and Reload to get the dialog to the original state.
Review the dialog Sample 2.js (in the development folder) that allows you to Reorder variables in the dataset alphabetically by inspecting the code in Notepad++ or a Javascript editor.
Note: The R function BSkySortDataset mentioned below is already created in the BlueSky Package
{{dataset.name}} <- {{dataset.name}} %>% dplyr::select(sort(names(.)))
{{dataset.name}} <- {{dataset.name}} %>% dplyr::select(rev(sort(names(.))))
BSkySortDataset <- function (alphabeticalSort = TRUE, data = datasetName)
{
if (alphabeticalSort)
{
data<- data %>% dplyr::select(sort(names(.)))
} else
{
data <- data %>% dplyr::select(rev(sort(names(.))))
}
}
require(dplyr)
{{dataset.name}} <- BSkySortDataset(alphabeticalSort ={{selected.rdgrp}}, data ={{dataset.name}})
BSkyLoadRefresh("{{dataset.name}}" )
require(dplyr)
#Reorder variables alphabetically in order A-Z
admit <- admit %>% dplyr::select(sort(names(.)))
BSkyLoadRefresh("admit")
admit <- BSkySortDataset(alphabeticalSort =TRUE, data =admit)
BSkyLoadRefresh("admit")
{{if (options.selected.rdgrp=="TRUE")}}
R code to execute when true
{{#else}}
R code to execute when false
{{/if}}
{{if (options.selected.rdgrp=="TRUE")}}
R code to execute when false
{{/if}}
require(dplyr)
{{if (options.selected.rdgrp=="TRUE")}}#Reorder variables alphabetically in order A-Z\n{{dataset.name}} <- {{dataset.name}} %>% dplyr::select(sort(names(.)))\n{{#else}}#Reorder variables alphabetically in order Z-A\n{{dataset.name}} <- {{dataset.name}} %>% dplyr::select(rev(sort(names(.))))\n{{/if}}
BSkyLoadRefresh("{{dataset.name}}" )
{{if (options.selected.generateplotchk == "TRUE")}}
#Displaying plots\nplot({{selected.modelname | safe}})
{{/if}}
You may need to create dialogs that populate a preformatted text control or combobox with the results of a R function. For example see Model Evaluation > Plot a Model. When you launch this dialog we automatically show you all the models of class lm (linear models) and glm (generalized linear models).
NOTE: This capability is only available with a combobox and a
preformatted text control.
If used with a combobox the R function must return a character or
numeric vector, each element of the vector returned will be displayed as
an entry in the combobox. If used with a textbox, the R function must
return a character string. The character string will be displayed in the
preformatted text control.
pre_start_r: JSON.stringify({
Value of the no property: "Name of the R function",})
pre_start_r: JSON.stringify({
modelselector1: "BSkyGetAvailableModels(c(\"lm\", \"glm\"))",})
onclick: `r_before_modal("${config.id}")`,
modal_id: config.id
nav: {
name: "Name that displays in the navigation",
icon: "suitable icon",
onclick: `r_before_modal("${config.id}")`,
modal_id: config.id
},
Use this dialog as a starting point to copy/paste template controls into the new dialog you are building.
Here are a couple or more advanced scenarios 1. You want a single control to create different R code e.g. one R function needs the variables in the format c(“var1”,“var2”, “var3”) and another R function associated with the same dialog wants the variables in the format var1 + var2 + var3 2. You may want to perform some validation based on the data entered e.g. check whether the user logged in has write permissions to the path selected etc.
The cases above are handled on post processing after the user clicks the execute function.
Follow the steps below
var code_vars = {
dataset: {
name: $(`#${instance.config.id}`).attr('dataset') ? $(`#${instance.config.id}`).attr('dataset') : getActiveDataset()
},
selected: instance.dialog.extractData()
}
const cmd = instance.dialog.renderR(code_vars);
res.push({ cmd: cmd, cgid: newCommandGroup() })
return res;
vars = code_vars.selected.commaSepDest.toString();
if (code_vars.selected.Interaction == "FALSE") {
code_vars.selected.dependentVars = vars.replace(",", "*");
}
else {
code_vars.selected.dependentVars = vars.replace(",", "+");
}
//Creating a string for interaction plots
code_vars.selected.stringInteractionPlots = vars.replace(",", "~");
When you write javascript code to create dialogs, just like any programmer, there is a likelihood that you will see the following errors. We do our best to check for these errors on dialog installation. What follows are some of the common errors you will encounter.
RCode: `
require(equatiomatic)
require(textutils)
#Creating the model
{{selected.modelname1 | safe}} = lm({{selected.dependent | safe}}~{{selected.independent | safe}}, {{ if (options.selected.weights != "")}}weights ={{selected.weights | safe}},{{/if}} na.action=na.exclude, data={{dataset.name}})
Upload and install dialog Sample 11.js.
Paste the syntax, you will see the line below. As the application could not find a control with a no property set to “modelname1”, it substitutes undefined
#Creating the model
undefined = lm(engine~weight+accel+year+origin+cylinder, na.action=na.exclude, data=caranalysisDelete)
RCode: `
require(equatiomatic)
require(textutils)
#Creating the model
{{selected.modelname | safe}} = lm({{selected.dependent | safe}}~{{selected.independent | safe}}, {{ if (options.selected.weights != "")}}weights ={{selected.weights | safe}},{{/if}} na.action=na.exclude, data={{dataset.name}})
Rcode:`
convert_lm_type = {{selected.modelname | safe}}
class(convert_lm_type) = "lm"
BSkyFormat(convert_lm_type)`
See incorrect R code generated when the newline character gets removed by the templating engine
convert_lm_type = linearModelclass(convert_lm_type) = "lm"
BSkyFormat(convert_lm_type)`
This can be addressed in the following ways 1. Place a ; at the end of the line, see below
Rcode:`
convert_lm_type = {{selected.modelname | safe}};
class(convert_lm_type) = "lm"
BSkyFormat(convert_lm_type)`
or 2. Place a newline character at the end of the line
Rcode:`
convert_lm_type = {{selected.modelname | safe}}\n
class(convert_lm_type) = "lm"
BSkyFormat(convert_lm_type)`
The code below will not show the line
qqnorm(residuals(model1))
qqline(residuals(model1))
The code below will display the line correctly
{
qqnorm(residuals(model1))
qqline(residuals(model1))
}
Delete the “BlueSky Statistics” folder from “Roaming” directory
(This applies to Windows operating system). On the Windows operating
system, you can access the roaming folder by opening the Windows
Explorer and typing %appdata% in the control that displays the path. The
path of the folder is typically
c:\users\
Delete the user dialog folder (or just delete the entire contents of the folder). You can access the path that you set to save manually installed dialogs by clicking the hamburger menu ( 3 sandwiched lines) on the top left of the main application Window, click on Marketplace. If you have other files that are not related to the BlueSky Statistics application in this folder, then delete the dialog.json and the javascript files related to the user dialogs that you installed/uploaded.