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
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"
extraction: "NoPrefix|UseComma|Enclosed"
dependent: {
el: new dstVariable(config, {
label: localization.en.dependent,
no: "dependent",
filter: "String|Numeric|Logical|Ordinal|Nominal",
extraction: "NoPrefix|UseComma",
required: true,
}),
},
Reference the value of the no property of the control enclosed in the format required by the Squirrelly templating engine within the R code, see the example below the no property is “dependent”. Note, in the example below the glm function takes a number of parameters, i.e. the modelname, the dependent variable and the independent variables. In this example we are concerned with the dependent variable
{{selected.dependent | safe}}
Rcode:`{{selected.modelname | safe}}= glm({{selected.dependent | safe}} ~ {{selected.independent | safe}}….`
E.g. If dependent variable control contains var1, var2, var3, and extraction is set to ‘NoPrefix|UseComma|Enclosed’, see above for extraction details then myVariables = c(‘var1’, ‘var2’, ‘var3’) will be substituted in the example below
{{selected.dependent | safe}}
Rcode:`myVariables= c({{selected.dependent | 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: 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: 'modelname'
label: String displayed above the textbox
label: "Enter model name"
placeholder: Optional default string displayed in the textbox, default is the empty string.
placeholder: "Logistic1"
required: Optionally force the user to enter a value in the textbox. Dialog will not execute unless a user specifies a value. Default is false.
required:false
allow_spaces: Optionally enforce entering a string that conforms to R’s rules for naming objects, default is false i.e., enforce R rules
allow_spaces:true
Type: "numeric"
allow_spaces:true
Type: "character"
extraction: Control how the entered text gets substituted in the R code
extraction: "TextAsIs"
extraction: "CreateArray"
extraction: "Prefix"
extraction: "Prefix|Enclosed"
extraction: "CreateArray|RemoveSpaces“
type: Optionally force the user to enter a numeric or character, defaults to character
type: "character"
type: "numeric"
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"
Sample Code for entering strings that must conform to R object name rules
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
bs_type: “checkbox”
bs_type: “valuebox”
state: "checked"
state: ""
extraction: "Boolean"
extraction: "TextAsIs"
true_value: "This is true"
false_value: "This is false"
NOTE THE INCORRECT SPELLING OF DEPENDANT IN DEPENDANT_OBJECTS BELOW. WE WILL CORRECT THIS IN A UPCOMING UPDATE
dependant_objects: ["input_no_value", "input_value"]
style="ml-1 mt-1 mb-3"
style="ml-2"
style="mb-2"
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,
})
},
Example 4: Enable the dependent control with no: “variablename” when the checkbox is checked
NOTE THE INCORRECT SPELLING OF DEPENDANT IN DEPENDANT_OBJECTS BELOW. WE WILL CORRECT THIS IN A UPCOMING UPDATE
storeClusterInDataset: {
el: new checkbox(config, {
label: localization.en.stroreClusterInDataset,
no: "storeclusterInDataset",
dependant_objects: ["variablename"],
extraction: "Boolean"
})
},
variablename: {
el: new input(config, {
no: 'variablename',
label: localization.en.variablename,
ml: 4,
placeholder: "",
type: "character",
extraction: "TextAsIs",
value: ""
})
},
Example 5: Enable the dependent control with no: “variablename” when the checkbox is checked and force the user to enter a value (when the checkbox is checked). Setting required:true in the checkbox forces the user to enter a value. When a value is not entered, the user gets a message when the dialog is executed.
NOTE THE INCORRECT SPELLING OF DEPENDANT IN DEPENDANT_OBJECTS BELOW. WE WILL CORRECT THIS IN A UPCOMING UPDATE
storeClusterInDataset: {
el: new checkbox(config, {
label: localization.en.stroreClusterInDataset,
no: "storeclusterInDataset",
required: true,
dependant_objects: ["variablename"],
extraction: "Boolean"
})
},
variablename: {
el: new input(config, {
no: 'variablename',
label: localization.en.variablename,
ml: 4,
placeholder: "",
type: "character",
extraction: "TextAsIs",
value: ""
})
},
{{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}}`
* Simplifies the creation of an expression/formula by providing a set of arithmetic, logical, mathematical, string, type conversion, statistical, random number and date functions grouped into tabs * Click on the tab to see the functions corresponding to the name of the tab i.e. arithmetic, logical, mathematical… * Double clicking on a symbol will insert the symbol * You can drag and drop variables to create an expression/formula * Clicking a selected button will toggle its state. * To insert at a particular position in the textbox associated with the compute builder control, place the cursor in that position and drag and drop/move variable(s). * Mouse over a button for help.
no: "computeCtrl"
label:"Expression builder"
required:false
placeholder: "Create your expression here, for e.g. var1+var2+ceiling(var3)"
#### Compute Builder Sample Code
computeBuilder: {
el: new computeBuilder(config, {
no: "computeCtrl",
required:true,
label: "Expression builder",
placeHolder: "For e.g. var1+var2+ceiling(var3)"
})
},
{{selected.computeCtrl | safe}}
Rcode:`{{selected.computeCtrl | safe}},`
no: "formulaCtrl"
label:“Formula Builder"
required:false
placeholder: "Formula appears here"
#### Formula Builder Sample Code
formulaCtrl: {
el: new formulaBuilder(config, {
no: "formulaCtrl",
label: "Formula builder",
required:true,
placeHolder: "Create your formula here"
})
},
{{selected.formulaCtrl | safe}}
Rcode:`~{{selected.formulaCtrl | safe}},`
no: "timeZoneOptions"
name: "Advanced"
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}}")`
When your dialogs create graphs, you would want them to use the default themes available in the BlueSky Statistics application so that titles, fonts, graph themes look consistent across the application. You can access the themes used in the graphs that ship with BlueSky Statistics by going to triple dot>Theme. A user can change these themes.
In order to do so, all you need to do is append a + {{selected.BSkyThemes | safe}} \n at the end of your ggplot function and we will automatically append a string that contains the default themes
ggplot(data={{dataset.name}}, aes(x = col[[1]])) +
geom_histogram(bins = {{selected.histBins | safe}},
alpha=1, fill ="#727272",
aes(y =..density..)) +
stat_function(fun = dnorm,
args = list(mean = mean(var_list[[i]], na.rm = TRUE) ,
sd = sd(var_list[[i]], na.rm = TRUE)) ,
col = "#eaf820", size = 2) +
labs(x=names(col), title= paste("Histogram for variable", names(col))) +
xlab(names(col)) +
ylab("Density") + {{selected.BSkyThemes | safe}} \n
Results in the following code being substituted
geom_histogram(bins = 9, alpha=1, fill ="#727272" , aes(y =..density..)) +
stat_function(fun = dnorm,
args = list(mean = mean(var_list[[i]], na.rm = TRUE) ,
sd = sd(var_list[[i]], na.rm = TRUE)) ,
col = "#eaf820", size = 2) +
labs(x=names(col), title= paste("Histogram for variable", names(col))) +
xlab(names(col)) +
ylab("Density") +
theme_classic() +
theme(text=element_text(family="sans",
face="plain",
color="#000000", size=12,
hjust=0.5, vjust=0.5),
plot.title=element_text(hjust=.5, size=18))
All sample dialogs are located in the development folder in the installation directory (Default installation directory is c:\program files\BlueSky Statistics\10 folder)
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.