--- title: "SOCI832 Lesson 4.2 Regression diagnostics" lastmod: 2019-01-07T00:00:00.000Z draft: true type: docs maths: true output: blogdown::html_page: toc: true linktitle: "4.2 Regression: Diagnostics" menu: docs: parent: SOCI832 weight: 420 ---
ReadingField, A., Miles, J., and Field, Z. (2012). Discovering statistics using R. Sage publications.
|
ConceptsLevel 1Level 2 Level 3 |
SummaryThis is a 300 word summary of clase |
This week we are going to deal with three main topics: (1) dummy variables and interaction effects; (2) regression diagnostics; and (3) logit and probit regressions.
setwd("C:/G/2018, SOCI832/Datasets/AES 2013/")
install.packages("readr",
repos = 'http://cran.rstudio.com')
## Installing package into 'C:/Users/nickh/Documents/R/win-library/3.5'
## (as 'lib' is unspecified)
## package 'readr' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\nickh\AppData\Local\Temp\RtmpU9FvgO\downloaded_packages
library(readr)
elect_2013 <- read.csv("elect_2013.csv")
In the first section of this week we will learn about how to create, run, and interpret dummy variables and interaction effects.
Dummy variables are a fancy name for variables that are binary variable - with just two values - 0 and 1. Dummy variables are particularly important when we have to analyse catagorical variables.
Remember that categorical variables are those where there are many levels or potential values of the variable but those values or levels have no numeric meaning or ranking. Examples of categorical variables include:
Notice that in each of these cases the values of variable (english, sociology, maths, etc.) have no rank or mathematical equivalent meaning. Instead the values of the variable are ‘boxes’: they are just categories in which to place stuff - or more precisely, they are labels which we attach to our units of analysis (students).
But what does the existence of categorical variables have to do with the need for dummy variables? Well, the problem is that we want to do statistics with categorical variables, and, in particular, we want to include categorical variables as predictors (independent variables) in linear regression models.
The best way I can illustrate the problem with categorical variables is to tell you a problem I had for almost every term I taught in Singapore for the ten years I was there. Singapore has a racial classification system where everyone with citizenship is assigned as either Chinese, Indian, Malay, or Other (CIMO). In my classes, students would do various surveys, and when they did they would ask people their race as a matter of course. And then they would code it in their excel spreadsheets before importing into R (or SPSS). And they would code Chinese as 1, Indian as 2, Malay as 3, and Other as 4.
And then there would always be at least one group each semester who would run a regression - where the outcome was something like support for gay marriage - and they would put ‘race’ in as a variable. Now no matter whether they found that the variable was significant or not, they would have a problem if they just put it in as normal variable. If you just put a variable in as a standard variable, then R is going to interpret it as a numeric or continuous variable, where the numbers are units on some scale. And when students would do this with race, I would always ask “Is an Indian twice as much race as a Chinese person?” And is a Malay three units of race while Chinese only one? Clearly such questions are silly. Why? Because you can’t reduce races to multiples of each other! And it turns out that this is the case with virtually all the different values of categorical variables.
So how do we deal with this instead? Well dummy variables is the most common solution which statisticians have converged on. In essence a dummy variable is the extraction of one value of a categorical variable and the transformation of it into a single variable that has the value of one when the category exists and a value of zero when it doesn’t.
And we say that we ‘dummy out’ a categorical variable when we transform all the values of a categorical variable into their own dummy variables. For example, we could ‘dummy out’ the race variable in a Singaporean dataset by creating four variables: Chinese, Indian, Malay, and Other. And for each of these variables, the value would be 1 (one) if the individual had that characteristics, and zero otherwise. So, for example, an indian student would have zero for the ‘chinese’ variable, one for the ‘indian’ variable zero for the ‘malay’ variable, and zero for the ‘other’ variable.
There are a few different strategies you can use to dummy-out categorical variables.
The easiest thing to do, if you are doing a regression model, is to put the variable name inside the function ‘as.factor()’.
Compare the following two regression models
summary(lm(elect_2013$pol_knowledge ~ elect_2013$highest_qual))
##
## Call:
## lm(formula = elect_2013$pol_knowledge ~ elect_2013$highest_qual)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.8298 -2.7734 0.1815 2.2153 5.2379
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.84104 0.08741 55.384 <2e-16 ***
## elect_2013$highest_qual -0.01127 0.02149 -0.525 0.6
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.893 on 3793 degrees of freedom
## (160 observations deleted due to missingness)
## Multiple R-squared: 7.253e-05, Adjusted R-squared: -0.0001911
## F-statistic: 0.2751 on 1 and 3793 DF, p-value: 0.5999
summary(lm(elect_2013$pol_knowledge ~ as.factor(elect_2013$highest_qual)))
##
## Call:
## lm(formula = elect_2013$pol_knowledge ~ as.factor(elect_2013$highest_qual))
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.1608 -2.1608 0.0711 2.0711 6.0711
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.92889 0.08239 47.687 < 2e-16
## as.factor(elect_2013$highest_qual)2 2.23190 0.14752 15.130 < 2e-16
## as.factor(elect_2013$highest_qual)3 1.73288 0.13880 12.485 < 2e-16
## as.factor(elect_2013$highest_qual)4 1.67825 0.22857 7.342 2.55e-13
## as.factor(elect_2013$highest_qual)5 1.50603 0.17616 8.549 < 2e-16
## as.factor(elect_2013$highest_qual)6 0.46510 0.13517 3.441 0.000586
## as.factor(elect_2013$highest_qual)7 0.12611 0.16087 0.784 0.433131
##
## (Intercept) ***
## as.factor(elect_2013$highest_qual)2 ***
## as.factor(elect_2013$highest_qual)3 ***
## as.factor(elect_2013$highest_qual)4 ***
## as.factor(elect_2013$highest_qual)5 ***
## as.factor(elect_2013$highest_qual)6 ***
## as.factor(elect_2013$highest_qual)7
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.763 on 3788 degrees of freedom
## (160 observations deleted due to missingness)
## Multiple R-squared: 0.08884, Adjusted R-squared: 0.0874
## F-statistic: 61.56 on 6 and 3788 DF, p-value: < 2.2e-16
Notice that for the first model there is no effect of highest_qualification on political_knowledge. However in the second, quite a few of the dummy variables - levels 2, 3, 4, 5, and 6 - all have a positive effect on political_knowledge. Why do you think this is?
The answer is contained in the code book, which can be found here: https://mqsociology.github.io/learn-r/soci832/codebook%20aes%202013.html
You will notice that categories are not in a meaningful order: for example, 1 = no qualifications; 2 = postgrad degree; and 5 = diploma. This is why in the first model there was no signficant effect of the variable.
This example also shows the importance of dummy variables and dummying out categorical variables. Using the same data, we were able to go from a model with no explanatory power (R-squared = 0) to a decent model (R-squared = 0.09).
Another option is the package ‘fastDummies’. The advantage of this package is that it creates the dummy variables in your dataset, which gives you the freedom to do what you want and need to the variables - such as using them in correlations or descriptive statistics or transforming them. It also gives you the freedom to include some dummy variables in your model and not include others.
install.packages("fastDummies",
repos = 'http://cran.rstudio.com')
## Installing package into 'C:/Users/nickh/Documents/R/win-library/3.5'
## (as 'lib' is unspecified)
## package 'fastDummies' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\nickh\AppData\Local\Temp\RtmpU9FvgO\downloaded_packages
library(fastDummies)
The command can be seen here. In this we are dummying out the highest_qual variable.
elect_2013_dummies <- dummy_cols(elect_2013,
select_columns = c("highest_qual"))
Notice that we have created a new dataset. If you take a look at the dataset, it is exactly the same as elect_2013 except that it has the dummy variables added to the end of the data frame (they are called highest_qual_1, highest_qual_2, etc.).
Sometimes one characteristic of our lives changes how two other aspect of our lives effect each other. For example, if I have just had a fight with my partner, then problems at work effect my stress levels a lot more. Normally problems at work have only a minor effect on my stress levels, but when I have conflict with my partner, small problems at work make me feel very stressed. In this case, we say that the interaction between “partner conflict” and “problems at work” has a significant effect on “stress levels”.
But how do we actually model this statistically? It turns out that modelling of interaction effects are relativley straight forward, and we just need to follow some basic principles.
First, the interaction of two independent (i.e. potentially causal) variables is measured by multiplying the two variables.
This generally works for all types of variables - whether they are counts, continuous, or binary variables.
You can understand how this works by thinking of the archtypical case of two binary variables interacting. For example, ‘conflict at home’ and ‘problem at work’. If we were to multiply these two variables, we can think about how the subsequent variable - which we would call something like: ‘confict_at_home*problem_at_work’ - would have a 1 if I had both conflict at home and a problem at work, and a zero otherwise.
When we subsequently put this variable into a regression (or any other analysis) it would capture the effect of both variables being present at the same time.
The second key rule to remember is that we need to make sure we include both the original variables (the ones being multiplied) in any model.
We call these original variables ‘main effects’. It is important to include ‘main effects’ in models that have ‘interaction effects’ in them because otherwise we can’t be sure whether any correlation between the interaction effect and the outcome (dependent) variable is due to one of the variables on their own, or due to the actual interaction.
To return to the example of my stress, conflict at home, and problems at work. If we only put the interaction between conflict at home and problems at work a the model, then we did see a significant effect of this interaction on stress levels, we would have no way of knowing if the stress was caused by the interaction, or by one or the other of the main effects.
There is a problem, however, with including main effects and the interaction in the same regression model. This problem is that the interaction effect and the main effects are often highly correlated.
As we will learn in the next section on regression diagnostics, one of the problems with highly correlated variables in a regression model is that they violate model assumptions and produce results that are unreliable and potentially false.
In regression diagnostics, this problem of high correlation between main effects and interaction effects shows up as a high ‘Variance Inflation Factor’ (generally just called VIF). This will be explained in the next section, but I mention it to simply draw the link from the next section back to this material.
The way that this problem can be reduced is through a very simple mathematical transformation: centering variables prior to multiplication.
Centering is an incredibly simple process: for each variable, we simply subtract the mean of the variable from each case. This moves the mean of the variable to zero.
For interaction effects, we simply centre each variable before multiplying it. This greatly reduces the correlation of the interaction effect with the main effects, while not changing any meaning of the interaction variable in the regression model.
Why this works is not something I can definitively explain, but I believe it has to do with the fact that mean centring - by making half the values of both variable negative, and most cases values quite close to zero - removes much of the incidental correlation between main effect and interaction effect that comes from having the same units of measurement.
R Script
To run interaction effects in R, you have at least two options: to let lm() generate them for you, or to make them yourself.
It is quite easy to ask lm() to include an interaction effect: you simply type the two variables with a * between them, symbolizing a multiplication sign. lm() then includes the interaction effect and the two main effects. For example:
model_1 <- lm(elect_2013$likelihood_vote ~
elect_2013$internet_skills*elect_2013$age_18_24)
summary(model_1)
##
## Call:
## lm(formula = elect_2013$likelihood_vote ~ elect_2013$internet_skills *
## elect_2013$age_18_24)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.5609 -0.4131 0.5130 0.6608 1.5688
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 4.26531 0.02987
## elect_2013$internet_skills 0.07389 0.01280
## elect_2013$age_18_24 -1.55212 0.26150
## elect_2013$internet_skills:elect_2013$age_18_24 0.28509 0.07870
## t value Pr(>|t|)
## (Intercept) 142.812 < 2e-16 ***
## elect_2013$internet_skills 5.773 8.43e-09 ***
## elect_2013$age_18_24 -5.935 3.19e-09 ***
## elect_2013$internet_skills:elect_2013$age_18_24 3.623 0.000295 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.048 on 3819 degrees of freedom
## (132 observations deleted due to missingness)
## Multiple R-squared: 0.02784, Adjusted R-squared: 0.02707
## F-statistic: 36.45 on 3 and 3819 DF, p-value: < 2.2e-16
You can see that all three effects are significant: the main effect of internet_skills is positive, showing that better internet_skills correlate with a higher likelihood of voting; in contrast the main effect of being 18-24 years of age is negative, suggesting in general young people express a lower likelihood of voting if voting was not compulsory. However, the interaction effect tells us that young people who have better internet skills are more likely to express a belief that they will be likely to vote if voting wasn’t compulsory. This is a simple model which actually illustrates one of the main arguments of the McAllister paper, which is that the internet does, to some extent, counter act some of the decline in political interest of modern young people.
The other alternative is to make the interactioneffects ourselves.
This is quite simple, we simply create a new variable:
elect_2013$internet_skills.x.age_18_24 <- elect_2013$internet_skills*elect_2013$age_18_24
We then include the three variables in our model, and hopefully we will get exactly the same results
model_1 <- lm(elect_2013$likelihood_vote ~
elect_2013$internet_skills +
elect_2013$age_18_24 +
elect_2013$internet_skills.x.age_18_24)
summary(model_1)
##
## Call:
## lm(formula = elect_2013$likelihood_vote ~ elect_2013$internet_skills +
## elect_2013$age_18_24 + elect_2013$internet_skills.x.age_18_24)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.5609 -0.4131 0.5130 0.6608 1.5688
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) 4.26531 0.02987 142.812
## elect_2013$internet_skills 0.07389 0.01280 5.773
## elect_2013$age_18_24 -1.55212 0.26150 -5.935
## elect_2013$internet_skills.x.age_18_24 0.28509 0.07870 3.623
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## elect_2013$internet_skills 8.43e-09 ***
## elect_2013$age_18_24 3.19e-09 ***
## elect_2013$internet_skills.x.age_18_24 0.000295 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.048 on 3819 degrees of freedom
## (132 observations deleted due to missingness)
## Multiple R-squared: 0.02784, Adjusted R-squared: 0.02707
## F-statistic: 36.45 on 3 and 3819 DF, p-value: < 2.2e-16
we could also, if we desired, centre (mean centre) the interaction term with the following equation.
elect_2013$centred.internet_skills.x.age_18_24 <-
(elect_2013$internet_skills-
mean(elect_2013$internet_skills,
na.rm = TRUE))*(elect_2013$age_18_24-
mean(elect_2013$age_18_24, na.rm = TRUE))
model_1 <- lm(elect_2013$likelihood_vote ~
elect_2013$internet_skills +
elect_2013$age_18_24 +
elect_2013$centred.internet_skills.x.age_18_24)
summary(model_1)
##
## Call:
## lm(formula = elect_2013$likelihood_vote ~ elect_2013$internet_skills +
## elect_2013$age_18_24 + elect_2013$centred.internet_skills.x.age_18_24)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.5609 -0.4131 0.5130 0.6608 1.5688
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) 4.23372 0.02999 141.176
## elect_2013$internet_skills 0.09032 0.01287 7.020
## elect_2013$age_18_24 -1.00413 0.12418 -8.086
## elect_2013$centred.internet_skills.x.age_18_24 0.28509 0.07870 3.623
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## elect_2013$internet_skills 2.61e-12 ***
## elect_2013$age_18_24 8.19e-16 ***
## elect_2013$centred.internet_skills.x.age_18_24 0.000295 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.048 on 3819 degrees of freedom
## (132 observations deleted due to missingness)
## Multiple R-squared: 0.02784, Adjusted R-squared: 0.02707
## F-statistic: 36.45 on 3 and 3819 DF, p-value: < 2.2e-16
This last version is probably slightly better than the other options, because the mean centreing reduces multicollinarity and that reduces the standard errors and increases the signficance of the main effects in the model.
In this next section we are going to change gear a little and go back to thinking about linear regressionn models.
Any model is only valid if the assumptions it is based on are true. This is true for linear regression models, as it is for any model.
For linear regression models, there are really two very different parts:
For each of these parts of the model, there are different assumptions. In general, the assumptions that underly the coefficients are about the proper fit (or) otherwise of the coefficients to the sample (i.e. does the line estimating the relationship between the IV and DV pass through the middle of the points on a graph). In contrast, the assumptions related to the standard error are about the ability of the model to be generalised to the larger population: these tend to be about whether the standard errors properly reflect the likely variation (or non-variation) in the value of the population parameter.
For each of the various assumptions, there are three questions to ask (1) ASSUMPTION: what is the assumption; (2) TEST: how do we test the assumption - also called a diagnostic test - ; and (3) TREATMENT: how do we fix or address this problem if we find it.
One basic ASSUMPTION of all models is that there are very few ‘outliers’. An outlier is a case (a unit of analysis - e.g. survey respondent) whose value on the outcome variable (dependent variable) is poorly explained by the explanatory variables (independent variables).
The reason outliers are a problem is that they show that the model is a bad explanation of the data. Basically it’s a bad model.
How do we TEST if we have outliers? We look to see if there is a large amount of unexplained dependent variable for any particular case. Remember that for a linear regression model the explained part of the dependent variable is the value of the dependent variable as predicted by all the independent variables.
For example, say estimate a model of likelihood of voting (from 1 to 5) as predicted by political knowledge (measured from 0 to 10 on quiz).
Suppose that the estimated model is:
\[\text{likelihood_vote}=0.5*\text{pol_knowledge}\]
And suppose we have a person called “Tom” with a likelihood of voting of “1”, and a political knowledge of 6. Tom’s predicted likelihood_vote would be 6*0.5 = 3. However, his actual likelihood is 1, so the unexplained part of his vote is 3 minus 1 = 2.
We call this unexplained part of outcome variable the residual.
Outliers are identified by the fact that they have very large residuals.
Now it turns out that since variables are measured in many different units of analysis, we need to standardise the units of analysis of residuals so that they have some universal unit.
And you will remember from previous classes the main way we standardise and create universal units is by dividing values by the standard deviation of those values so that a case with a value of 1 is is known to have residuals exactly one standard deviation away from the coefficient.
So the measure we use to TEST for outliers is ‘standardised residuals’.
We calculate the value of this on all the cases in our dataset, and then we look at the proportion of those that lie outside what you would expect to find by chance.
And how do we do that? We look to see how many have standardized residuals that are different from those expected in a normal distribution.
And this test is quite straightforward. We expect
Let’s look at how we do this in R
First we need to run a model. In this case we run a simple model of political knowledge, with one predictor: interest in politics.
model_1 <- lm(elect_2013$pol_knowledge
~ elect_2013$interest_pol
+ elect_2013$highest_qual
+ elect_2013$age_cat
+ elect_2013$female
+ elect_2013$tertiary_ed
+ elect_2013$income)
If you want to see this model’s coefficients, then you can run:
summary(model_1)
##
## Call:
## lm(formula = elect_2013$pol_knowledge ~ elect_2013$interest_pol +
## elect_2013$highest_qual + elect_2013$age_cat + elect_2013$female +
## elect_2013$tertiary_ed + elect_2013$income)
##
## Residuals:
## Min 1Q Median 3Q Max
## -7.7855 -1.7471 0.0307 1.7354 7.9574
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.027726 0.243182 20.675 <2e-16 ***
## elect_2013$interest_pol -1.382976 0.054180 -25.525 <2e-16 ***
## elect_2013$highest_qual 0.030033 0.019341 1.553 0.121
## elect_2013$age_cat 0.359838 0.029312 12.276 <2e-16 ***
## elect_2013$female -0.675186 0.081572 -8.277 <2e-16 ***
## elect_2013$tertiary_ed 1.156405 0.096796 11.947 <2e-16 ***
## elect_2013$income 0.066131 0.007171 9.222 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.373 on 3497 degrees of freedom
## (451 observations deleted due to missingness)
## Multiple R-squared: 0.3185, Adjusted R-squared: 0.3174
## F-statistic: 272.4 on 6 and 3497 DF, p-value: < 2.2e-16
Next we construct a new data frame which will hold the variables from our model.
I’ve given it the name ‘diagnostics’, but you could call it anything.
diagnostics <- model_1$model
You can view this data frame by double clicking on it in the top right corner of your RStudio window.
Next we want to put the main residuals into the new data frame. The most important of these is the third set - the standardised residuals
diagnostics$fitted.values <- model_1$fitted.values
diagnostics$residuals <- model_1$residuals
diagnostics$standardized.res <- rstandard(model_1)
diagnostics$student.res <- rstudent(model_1)
Now we need to run the tests.
Remember that the first test was 95%+ cases with standardised residuals between +/- 1.96. Another way to say this is “No more than 5% of cases with absolute value of standardised residual of greater than 1.96”.
How many cases is 5% of cases in your dataset? We can just measure the length of a variable to get the number of cases in our dataset and then multiply that by 0.05 MAXIMUM CASES EXPECTED >
length(diagnostics$standardized.res)*0.05
## [1] 175.2
Which is 197.1 for this model.
So how many cases in our dataset have an absolute value of the standardised residual of > 1.96:
ACTUAL NUMBER OF CASES IN THIS DATASET >
sum(abs(diagnostics$standardized.res) > 1.96)
## [1] 140
The equation above tells us it is 150, which is less that 197.1, and thus less than 5%.
We can repeat this with the other two tests
“No more than 1% of cases with absolute value of standardised residual of greater than 2.58”.
MAXIMUM CASES EXPECTED:
length(diagnostics$standardized.res)*0.01
## [1] 35.04
ACTUAL NUMBER OF CASES IN THIS DATASET:
sum(abs(diagnostics$standardized.res) > 2.58)
## [1] 20
“No more than 0.1% of cases with absolute value of standardised residual of greater than 3.29”.
MAXIMUM CASES EXPECTED:
length(diagnostics$standardized.res)*0.001
## [1] 3.504
ACTUAL NUMBER OF CASES IN THIS DATASET:
sum(abs(diagnostics$standardized.res) > 3.29)
## [1] 1
While outliers are cases that are not explained by a model, influential cases are those that disproportionately effect the coefficients of the model.
We can think of the influence of an individual case (e.g. one person who does our survey) by asking how much does the coefficient for a predictor variable in a model change when this one case is dropped out of the dataset.
There are many different measures of influential cases, and it is beyond this course to explain how these are calculated and exactly what they mean. For our purposes, the key things to understand are (1) what tests we should run ; and (2) how to judge whether our model passes these tests or not. In addition we may want to be able to answer (3) what should we do if our data fails the test.
The two measures of influential cases we are going to look at are:
Cook’s Distance is calculated on all cases (e.g. respondants) and a case is considered a problem - i.e. too influential - if it has a Cook’s Distance greater than 1.
Leverage is also calculated on all cases. There are different rules of thumb about what level of leverage is problematic. More than two or three times the average leverage is generally thought of as a problem. The average leverage, however, varies with the number of preditors in a model, and the number of observations in a dataset, so we need to calculate the maximum leverage for each model.
The forumula is:
\[\text{MAXIMUM LEVERAGE}=\frac{3(k+1)}{n}\]
\[\text{where:}\] \[k=\text{coefficients in model}\] \[n=\text{observations}\] ```
The various measures of influential cases can be calculated and stored with the following commands:
diagnostics$cooks.distance <- cooks.distance(model_1)
diagnostics$dfbeta <- dfbeta(model_1)
diagnostics$dffits <- dffits(model_1)
diagnostics$leverage <- hatvalues(model_1)
diagnostics$covariance.ratios <- covratio(model_1)
We can then check the maximum Cook’s Distance (which should be > 1) with this command:
max(diagnostics$cooks.distance)
## [1] 0.006945028
And then we can check that the maxmimum leverage is below the prescribed level of 3*(k+1)/n where k = coefficients in model and n = observations
k <- length(model_1$coefficients) - 1
n <- length(diagnostics)
\[\text{MAXIMUM LEVERAGE}= ((k + 1)/n)*3 \]
MAXIMUM LEVERAGE IN THIS DATA =
max(diagnostics$leverage)
## [1] 0.006453052
Another problem which a model can have is that the predictor variables (independent variables) are highly collinear.
Some level of collinearity is to be expected. However, when the correlation between variables is extreme - like 0.8 or 0.9 or higher - then this collinearity can undermine the quality of a linear regression model.
The problem is that such colinearity tends to inflate - i.e. artificially increase - the standard errors of coefficients. And if the standard errors are artificially larger, then predictor variables that are ACTUALLY statistically significant (i.e. p value < 0.05 and/or 95% confidence interval does not include zero), will APPEAR to be not significant.
The main way that we check for multicollinearity in a regression model is with the Variance Inflation Factor (VIF) (and it’s inverse, which is called ‘Tolerance’).
The rule of thumb is that the highest VIF for any coefficient in the model should be less than 10, and ideally less that 5 or ever 2.5.
Another rule of thumb is that the average VIF should not be substantially greater than 1. However, from what I can find in a casual search, it’s not clear exactly what ‘substantially greater than 1’ means. My reading is that the average should be below ~ 2 or 3.
To measure Variance Inflation Factor (VIF) we need to install and load the “car” package
install.packages("car",
repos = 'http://cran.rstudio.com')
## Installing package into 'C:/Users/nickh/Documents/R/win-library/3.5'
## (as 'lib' is unspecified)
## package 'car' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\nickh\AppData\Local\Temp\RtmpU9FvgO\downloaded_packages
library(car)
## Loading required package: carData
The VIF for each variable in a model is given by this command:
vif(model_1)
## elect_2013$interest_pol elect_2013$highest_qual elect_2013$age_cat
## 1.149687 1.094068 1.239463
## elect_2013$female elect_2013$tertiary_ed elect_2013$income
## 1.034434 1.240478 1.236355
If you don’t want to read and look for the maximum VIF, then you can use this command and check that the results is below the threshold of 10 (or more conservatively 5).
max(vif(model_1))
## [1] 1.240478
And you can check the mean VIF with this command:
mean(vif(model_1))
## [1] 1.165747
To illustrate the relevance of VIF and also of centring interaction effects, we will compare the VIF diagnostics for the two examples given in the ‘interaction effects’ section (1.2).
Below I’ve simply pasted the two linear regression models, and then run the three diagnostics. Remember that the maximum VIF should be below 10, and ideally below 5 or even 4. Run the code and interpret the results.
model_normal <- lm(elect_2013$likelihood_vote ~
elect_2013$internet_skills*elect_2013$age_18_24)
summary(model_normal)
##
## Call:
## lm(formula = elect_2013$likelihood_vote ~ elect_2013$internet_skills *
## elect_2013$age_18_24)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.5609 -0.4131 0.5130 0.6608 1.5688
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 4.26531 0.02987
## elect_2013$internet_skills 0.07389 0.01280
## elect_2013$age_18_24 -1.55212 0.26150
## elect_2013$internet_skills:elect_2013$age_18_24 0.28509 0.07870
## t value Pr(>|t|)
## (Intercept) 142.812 < 2e-16 ***
## elect_2013$internet_skills 5.773 8.43e-09 ***
## elect_2013$age_18_24 -5.935 3.19e-09 ***
## elect_2013$internet_skills:elect_2013$age_18_24 3.623 0.000295 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.048 on 3819 degrees of freedom
## (132 observations deleted due to missingness)
## Multiple R-squared: 0.02784, Adjusted R-squared: 0.02707
## F-statistic: 36.45 on 3 and 3819 DF, p-value: < 2.2e-16
elect_2013$centred.internet_skills.x.age_18_24 <-
(elect_2013$internet_skills-
mean(elect_2013$internet_skills,
na.rm = TRUE))*(elect_2013$age_18_24-
mean(elect_2013$age_18_24, na.rm = TRUE))
model_centred <- lm(elect_2013$likelihood_vote ~
elect_2013$internet_skills +
elect_2013$age_18_24 +
elect_2013$centred.internet_skills.x.age_18_24)
summary(model_centred)
##
## Call:
## lm(formula = elect_2013$likelihood_vote ~ elect_2013$internet_skills +
## elect_2013$age_18_24 + elect_2013$centred.internet_skills.x.age_18_24)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.5609 -0.4131 0.5130 0.6608 1.5688
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) 4.23372 0.02999 141.176
## elect_2013$internet_skills 0.09032 0.01287 7.020
## elect_2013$age_18_24 -1.00413 0.12418 -8.086
## elect_2013$centred.internet_skills.x.age_18_24 0.28509 0.07870 3.623
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## elect_2013$internet_skills 2.61e-12 ***
## elect_2013$age_18_24 8.19e-16 ***
## elect_2013$centred.internet_skills.x.age_18_24 0.000295 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.048 on 3819 degrees of freedom
## (132 observations deleted due to missingness)
## Multiple R-squared: 0.02784, Adjusted R-squared: 0.02707
## F-statistic: 36.45 on 3 and 3819 DF, p-value: < 2.2e-16
vif(model_normal)
## elect_2013$internet_skills
## 1.08217
## elect_2013$age_18_24
## 13.01775
## elect_2013$internet_skills:elect_2013$age_18_24
## 13.25670
vif(model_centred)
## elect_2013$internet_skills
## 1.093345
## elect_2013$age_18_24
## 2.935596
## elect_2013$centred.internet_skills.x.age_18_24
## 2.798454
max(vif(model_normal))
## [1] 13.2567
max(vif(model_centred))
## [1] 2.935596
mean(vif(model_normal))
## [1] 9.118872
mean(vif(model_centred))
## [1] 2.275798
The residuals - which are the difference between the predicted value (the value predicted by our model) of the dependent variable, and the actual observed value - should be distributed randomly and distributed with the same variance at all levels of the (predicted) dependent variable.
Why does this matter? It matters because when there is heteroscedasticity (i.e. not homoscedasticity) variance - and therefore standard errors are underestimated, making inference from the model to a population unsound.
The simplest way to test for homoscedasticity is to use a built in function in R, where you simply call the command ‘plot()’ and place the regression model data in the function.
plot(model_1)
Note that when you run this command, R will say to you in the console window:
"Hit <Return> to see next plot: "
When you hit
This first plot is the most important. It is the plot of the residuals against the fitted values of the dependent variable.
The general advice for evaluating this plot is that the values should be evenly distributed across the different values of the fitted values.
Heteroscedasticity normally manifests as a ‘funnel’ shape of the residuals, with small variance in residuals for low fitted values, and large residuals for high fitted values.
In practice, the plots which one sees are often hard to evaluate - especially for someone who is not an expert and experienced regression modeller and statistician.
In general I would recommend running this test and then referring to the textbook (Field et al. 2012: section 7.9.5), and websites such as this: http://www.contrib.andrew.cmu.edu/~achoulde/94842/homework/regression_diagnostics.html
Another assumption we can test is independence of errors. This is not normally a problem unless one has samples on the same people (e.g. in time series data) or some strong sequencing effect caused by sampling (e.g. you sample people who are friends or who are living in close geographic proximity).
A test for independence of errors is the Durbin Watson Test. The statistic for this test should be more than 1 and less than 3, and the p-value for the test should be greater than 0.05.
Note that because this test is a sequential test it is dependent on the sort order of the data.frame. If you change the sort order of the data.frame, or you randomise the order of cases, then the DW test will be different, and probably show independence of errors (even if this is untrue)
This is the command for running the D-W Test. Remember that the D-W Statistic should be between 1 and 3, and the p-value of the test should be greater than 0.05 >
durbinWatsonTest(model_1)
## lag Autocorrelation D-W Statistic p-value
## 1 0.006103426 1.987623 0.688
## Alternative hypothesis: rho != 0
One last assumption that we will test is the assumption that residuals are normally distributed.
We have already tested some aspects of the normal distribution when we tested for outliers (2.1).
However, a lack of outliers is only one aspect of a normal distribution. A distribution could - and often does - lack outliers but still not be normal. It could be very skewed with the values are mostly at one end of the range (e.g. a survey question where most people say ‘strongly agree’), or they could be bifucated with two peaks (e.g. heights of a group of parents and children on a hike).
In our case, we are not looking at a variable directly but rather the residuals of a variable. Nonetheless, the distribution of residuals has the potential, like any distribution, to not be normally distributed in many different ways.
One way to test for all these different possibilities is to just visually inspect the residuals. And we do this by simply visually inspecting the histogram of the standardised residuals.
The test we apply is rather rough, but is essentially: Does it look like a symetrical bell curve, centred on a standardised residual of zero?
If the answer is yes - more or less - then we are generally satisfied that the assumption holds.
There are more advanced tests - for measuring skewness, for example - but these are generally not used unless there is a very specific reason.
What do we visually inspect the standardised residuals? The command is simply:
hist(diagnostics$standardized.res)
In this case the residuals look normally distributed
However, we can come up with an example that violates this assumption of normality. Run the following code and inspect the standardised residuals.
model_2 <- lm(elect_2013$likelihood_vote
~ elect_2013$pol_knowledge)
diag2 <- model_2$model
diag2$standardized.res <- rstandard(model_2)
hist(diag2$standardized.res)
The visual inspection of the histogram shows a serious problem with skewness. One reason this happens because the dependent variable - likelihood_vote - is so skewed. Regardless, the point here is that there are models which fail this test.
What do we do if our data or model violates one or more of these assumptions?
There are lots of different techniques and tricks that can be used to address these problems. I will try to list some of the most common here:
Applying all these techniques is beyond this week’s class, but we will deal with many of these ideas over the course of the semester.
Next we are going to look at one type of model that does have few assumptions, and is often used when one or more of the assumptions discussed have been violated: the logistic regression model.
Given how much we have already covered, I am going to keep this short.
Some outcome variables are inherently binary: Death, catching a disease, being cured, and pregnancy, are all inherently binary outcomes.
Such outcomes violate many of the basic assumptions of linear regression models, and so we can’t use them. What would it mean that drinking a glass of red wine each night reduced your chance of dying by 0.1 units of death? It doesn’t make sense.
To deal with this inherent limitation of linear regression models, statistians developed the logistic regression (or logit) model, and also a related model called probit.
A logistic regression model still uses a linear model of the relationship between the predictor (independent) variables, and the outcome (dependent) variable. What logisitic regression models change is the ‘link’ - the function - by which one unit of predictor influences the outcome.
Where the equation for linear regression is:
\[y=\beta x+c\]
The equation for a similar logit is:
\[\text{Probability}(y=1) = \frac{1}{(1+e^{-(\beta x+c)})}\] \[\text{Where:}\] \[e=\text{base of natural log (approx 3)}\]
If that equation looks confusing to you DON’T WORRY, because it is!!!
And the good news is that you don’t really need to understand anything about it except that it allows us to estimate how much independent variable change the probablity that our outcome (y) will equal one.
While this equation looks scary, we are luck that at the heart of the logistic regression model is a very intuitive idea that when talking about binary outcomes - like death or pregnancy - we talk about changes in the ‘odds’ that an event will happen.
So when we are interpreting a logistic regression we say that a variable - such as eating salami everyday - doubles the odds of dying of heart disease (as compared to someone who doesn’t eat salami everyday).
When we are talking about ‘odds’ we are more or less talking about something similar to what people talk about in horse racing. Or what we are used to hearing when we read newspaper reports about the latest scientific study about how smoking or exercises increases or decreases our chance of an early death.
I strongly recommend reading Chapter 8: Logistic Regression of Field et al 2012. as it explains many of the more technical aspects of logistic regression models.
We are going to use a couple of new packages - the package ‘oddsratio’ makes it easy for us to calculate and display odds ratios for our models; - the package ‘rcompanion’ makes it easy for us to calculate r-squared for our models.
install.packages("oddsratio",
repos = 'http://cran.rstudio.com', dependencies=TRUE)
## Installing package into 'C:/Users/nickh/Documents/R/win-library/3.5'
## (as 'lib' is unspecified)
## package 'oddsratio' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\nickh\AppData\Local\Temp\RtmpU9FvgO\downloaded_packages
install.packages("rcompanion",
repos = 'http://cran.rstudio.com', dependencies=TRUE)
## Installing package into 'C:/Users/nickh/Documents/R/win-library/3.5'
## (as 'lib' is unspecified)
## package 'rcompanion' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\nickh\AppData\Local\Temp\RtmpU9FvgO\downloaded_packages
install.packages("zoo",
repos = 'http://cran.rstudio.com', dependencies=TRUE)
## Installing package into 'C:/Users/nickh/Documents/R/win-library/3.5'
## (as 'lib' is unspecified)
## package 'zoo' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\nickh\AppData\Local\Temp\RtmpU9FvgO\downloaded_packages
library(oddsratio)
library(rcompanion)
We are going to model likelihood of responding that they would definitely vote if voting was voluntary. Remember that this is a 5 on the 5 point likert scale for the varible likelihood_vote. And remember that most people gave this answer, which lead to the variable being difficult to model because the residuals were skewed.
Modelling this as a logistic regression and a binary outcome is one potential way to deal with the violation of this model assumption.
elect_2013$def_vote <- ifelse(elect_2013$likelihood_vote==5,1,0)
We are now going to make two models of ‘def_vote’. model1 will be just the impact of being australian born. model2 will include a large number of variables.
model1 <- glm(elect_2013$def_vote ~
elect_2013$aust_born, family = binomial)
summary(model1)
##
## Call:
## glm(formula = elect_2013$def_vote ~ elect_2013$aust_born, family = binomial)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.4912 -1.4112 0.8932 0.8932 0.9604
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.53456 0.06656 8.032 9.62e-16 ***
## elect_2013$aust_born 0.17847 0.07777 2.295 0.0217 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 4828.9 on 3768 degrees of freedom
## Residual deviance: 4823.6 on 3767 degrees of freedom
## (186 observations deleted due to missingness)
## AIC: 4827.6
##
## Number of Fisher Scoring iterations: 4
The main thing to note is that the coefficient of 0.178 for australian born is (1) significant; and (2) does not have an intuitive interpretation.
So this is why we instead estimate the odds ratio, which happens to be the exponential of the coefficient.
This function - or_glm - calculates this for us:
or_glm(data = elect_2013, model = model1)
## # A tibble: 1 x 5
## predictor oddsratio `CI_low (2.5)` `CI_high (97.5)` increment
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 elect_2013$aust~ 1.20 1.03 1.39 Indicator var~
The key number is in the output the 1.195 under the heading ‘oddsratio’.
In future weeks we will discuss exactly how to interpret this, but for the moment you can think of it as saying something like (and this is not true - but rather an analogy) if there were two groups - one of 200 foreign-born australians, and one of 200 Australian-born australians, and amongst the foreign born persons 100 say they will definitely vote, then of the 200 australian-born persons, 120 would say they will definitely vote.
We can also calcuate some equivalents of R-squared with this command. Note that there are several different measures that can be chosen from:
nagelkerke(model1)
## $Models
##
## Model: "glm, elect_2013$def_vote ~ elect_2013$aust_born, binomial"
## Null: "glm, elect_2013$def_vote ~ 1, binomial"
##
## $Pseudo.R.squared.for.model.vs.null
## Pseudo.R.squared
## McFadden 0.0459298
## Cox and Snell (ML) 0.0597519
## Nagelkerke (Cragg and Uhler) 0.0809068
##
## $Likelihood.ratio.test
## Df.diff LogLik.diff Chisq p.value
## -1 -116.11 232.21 1.9613e-52
##
## $Number.of.observations
##
## Model: 3769
## Null: 3926
##
## $Messages
## [1] "Note: For models fit with REML, these statistics are based on refitting with ML"
##
## $Warnings
## [1] "WARNING: Fitted and null models have different numbers of observations"
That is the end of the lesson for today.
By way of ending, I’ll leave you with a more elaborate logistic regression model, which you can try to interpret. Enjoy!
model2 <- glm(elect_2013$def_vote ~ elect_2013$pol_knowledge
+ elect_2013$age
+ elect_2013$female
+ elect_2013$income_quintiles
+ elect_2013$interest_pol
+ elect_2013$aust_born, family = binomial)
summary(model2)
##
## Call:
## glm(formula = elect_2013$def_vote ~ elect_2013$pol_knowledge +
## elect_2013$age + elect_2013$female + elect_2013$income_quintiles +
## elect_2013$interest_pol + elect_2013$aust_born, family = binomial)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.4116 -0.8186 0.4620 0.8067 2.3524
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.32733 0.28766 4.614 3.95e-06 ***
## elect_2013$pol_knowledge 0.14410 0.01693 8.514 < 2e-16 ***
## elect_2013$age 0.01056 0.00281 3.759 0.000171 ***
## elect_2013$female 0.32019 0.08541 3.749 0.000178 ***
## elect_2013$income_quintiles 0.03106 0.03360 0.924 0.355249
## elect_2013$interest_pol -1.19462 0.06446 -18.532 < 2e-16 ***
## elect_2013$aust_born 0.30241 0.09392 3.220 0.001282 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 4423.1 on 3472 degrees of freedom
## Residual deviance: 3519.7 on 3466 degrees of freedom
## (482 observations deleted due to missingness)
## AIC: 3533.7
##
## Number of Fisher Scoring iterations: 4
or_glm(data = elect_2013, model = model2)
## # A tibble: 6 x 5
## predictor oddsratio `CI_low (2.5)` `CI_high (97.5)` increment
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 elect_2013$pol_k~ 1.16 1.12 1.19 Indicator va~
## 2 elect_2013$age 1.01 1.00 1.02 Indicator va~
## 3 elect_2013$female 1.38 1.17 1.63 Indicator va~
## 4 elect_2013$incom~ 1.03 0.966 1.10 Indicator va~
## 5 elect_2013$inter~ 0.303 0.266 0.343 Indicator va~
## 6 elect_2013$aust_~ 1.35 1.12 1.63 Indicator va~
nagelkerke(model2)
## $Models
##
## Model: "glm, elect_2013$def_vote ~ elect_2013$pol_knowledge + elect_2013$age + elect_2013$female + elect_2013$income_quintiles + elect_2013$interest_pol + elect_2013$aust_born, binomial"
## Null: "glm, elect_2013$def_vote ~ 1, binomial"
##
## $Pseudo.R.squared.for.model.vs.null
## Pseudo.R.squared
## McFadden 0.303839
## Cox and Snell (ML) 0.357453
## Nagelkerke (Cragg and Uhler) 0.466176
##
## $Likelihood.ratio.test
## Df.diff LogLik.diff Chisq p.value
## -6 -768.08 1536.2 0
##
## $Number.of.observations
##
## Model: 3473
## Null: 3926
##
## $Messages
## [1] "Note: For models fit with REML, these statistics are based on refitting with ML"
##
## $Warnings
## [1] "WARNING: Fitted and null models have different numbers of observations"


Properties
can_vote
can_vote: boolean
comment_count
comment_count: number
curation_rewards
curation_rewards: number
delegated_vesting_shares
delegated_vesting_shares: string
guest_bloggers
guest_bloggers: any[]
json_metadata
json_metadata: string
last_account_recovery
last_account_recovery: string
last_account_update
last_account_update: string
last_owner_update
last_owner_update: string
last_post
last_post: string
last_root_post
last_root_post: string
last_vote_time
last_vote_time: string
lifetime_vote_count
lifetime_vote_count: number
market_history
market_history: any[]
memo_key
memo_key: string
next_vesting_withdrawal
next_vesting_withdrawal: string
other_history
other_history: any[]
post_count
post_count: number
post_history
post_history: any[]
posting_rewards
posting_rewards: number
proxied_vsf_votes
proxied_vsf_votes: number[]
received_vesting_shares
received_vesting_shares: string
recovery_account
recovery_account: string
reputation
reputation: string
reset_account
reset_account: string
reward_sbd_balance
reward_sbd_balance: string
reward_steem_balance
reward_steem_balance: string
reward_vesting_balance
reward_vesting_balance: string
reward_vesting_steem
reward_vesting_steem: string
savings_balance
savings_balance: string
savings_sbd_balance
savings_sbd_balance: string
savings_sbd_last_interest_payment
savings_sbd_last_interest_payment: string
savings_sbd_seconds
savings_sbd_seconds: string
savings_sbd_seconds_last_update
savings_sbd_seconds_last_update: string
savings_withdraw_requests
savings_withdraw_requests: number
sbd_balance
sbd_balance: string
sbd_last_interest_payment
sbd_last_interest_payment: string
sbd_seconds
sbd_seconds: string
sbd_seconds_last_update
sbd_seconds_last_update: string
tags_usage
tags_usage: any[]
to_withdraw
to_withdraw: number
transfer_history
transfer_history: any[]
vesting_balance
vesting_balance: string
vesting_shares
vesting_shares: string
vesting_withdraw_rate
vesting_withdraw_rate: string
vote_history
vote_history: any[]
voting_power
voting_power: number
withdraw_routes
withdraw_routes: number
withdrawn
withdrawn: number
witness_votes
witness_votes: any[]
witnesses_voted_for
witnesses_voted_for: number


| DOSE: T+ 0:00 |
25 mg |
insufflated |
DPT |
(powder / crystals) |
| T+ 6:00 |
5.0 mg |
oral |
5-MeO-DiPT |
(powder / crystals) |
| T+ 8:00 |
30 mg |
insufflated |
DPT |
(powder / crystals) |
| T+ 10:00 |
0.5 mg |
oral |
Pharms - Clonazepam |
(pill / tablet) |
| T+ 11:30 |
1 bowl |
smoked |
Cannabis |
(plant material) |
| T+ 11:30 |
5.0 ml |
oral |
1,4-Butanediol |
(liquid) |
Ealier in the day I had already insufflated 25 mg DPT an hour prior to attending my cousin's First Communion. I have not been to church for many years now. I am very experienced with this substance and thought it might help access my lost 'religiousness'. I felt my self tapping into a calmness I didn't expect to encounter. The priest had a soft whitish-green aura about him.  He is truly happy to be receiving communion. I remember my own communion, nervously chewing the stale wafer, wondering if they came in other flavors. I remember imagining a wafer covered in cheeze doodle dust...I felt warm, positive.
The stained glass windows were beautiful, the sun sparkling through, casting little rainbows on the hardwood floor. Singing with such a large group was exhilerating, freeing. I felt I was getting more out of the mass than the regular attendees. I could see the tiredness glazing on many eyes. I could see people fidgetting with their keys, watching the clock. Whispering to each other. I felt like I was in highschool again. The sermon made me feel like a student listening to a teacher. I wanted to shout aloud! This was merely a pretense of religion, very superficial. No one was sharing anything, except pew space and anxious stares. Why couldn't they feel the way I was, coursing with solemnity and spirituality? I the undercover pagan in their midst? I understand now why the Temple of the Ture Inner Light (mentioned by Shulgin) actually uses DPT as a sacrament.
Later on that night, the real experiment took place:
- 6pm: One human monkey was administered a 5mg oral dose of 5meo-DIPT. Onset was observed at 35 mins. Slight chest energy. Mood elevation is perhaps the most noticable effect. I am giddy for sure. Smirking.
- 7pm: Typical 5meo-DiIPT pleasant body high. Touch feels good. I go outside and sit in the fresh cut grass. I am tickled by the blades of grass. I enjoy watching clouds move across the sky. It's getting dark and I am hoping to see stars. For the past two nights I have seen shooting stars after only sitting for 15 mins. I live way up in the mountains, there is very little light pollution here. I notice slight visual enhancements, the soft orange fading into lavender sunset is extra colorful, or more likely I am just more aware of the fade between the colors. Many shades I don't have a name for.
- 8pm: 30mg DPT insufflated. This is where things got really interesting. This is a special synergy. I feel exhuberant! Visuals were mounting within moments. Things began to swirl and morph in a dance of sparks. I was seeing random color bursts and streaks in the darkness. Tree limbs swayed in the wind, forming endless mesh-lattice works. The tactile effects had me feeling as if I was melding with the tree I had chosen to rest against. It was very calming. Visions of the Greenman sprung to mind. I found myself apologizing in my thoughts for the recent destruction of much mountainside behind where I live. It seems the world needs another golf course. I am thinking of the part in GOONIES where Mikey says that he hopes they build a sand trap where his house is, and NEVER GET THEIR BALLS OUT! I feel the same.
- 9pm: Visuals are very intricate and artful. When I stare at something, it starts to vibrate and is soon part of a whorling dance of electrons. It is an awe inspiring view. I can feel THE FLOW. I am in its current. Waves of tactile pleasure pass over me. My body is full of childish energy and I find myself dancing alone in the woods in the dark to the music in my head.  My own personal rave with nature.
- 10pm: .5mg clonazepam to settle a slight, underlying anxiety that that has begun to form. My mood is still locked in the positive. The roses I order for my mother came early and I was unable to wait. I had to give them to my mom right then! They were 'Movie Star Roses,' which gave her a good laugh. I felt like Aldous Huxley as I stared into the flowers, at how alive they seemed(for now). Exquisite. I felt very grateful towards my mother. All the years of protecting my brother and I from an abusive alcoholic father, of suffering abuse herself. And now she is free, independent, and beautiful. I can see a child's face in her visage. I am lucky to have such a strong and wonderful woman as my mother. Today is also my Grandmother's 75th birthday! I am equally moved by her, my second mother. I have hugged her at least twenty times today. It has been an eventful day to say the least.
- 11:30: Things have dropped of considerably. MJ has a noticable jumpstart effect with the visuals. Although, they have reverted to strange geometries and tube thingies. More chaotic. I feel calm from the clonazepam. I decide to mix up 5ml 1,4B with OJ. It adds a contented feeling, a slight drunken euphoria. Today was a complete success.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


市场完整性
Market Integrity 防止价格偏离正常值太远:
- 价格保护价格区间
- 熔断机制
Price Banding¶
Price Banding only prevents a trader from bidding or offering at prices that appear to be unrealistic and potentially damaging to the marketplace
Price Band Variation (PBV), 控制限价的范围， 买的下限， 卖的上限， 当交易价格变换后， PBVR 会重新计算， Arkenstone 会拒绝所有超过范围的单子。
这个参考的价格：
- 盘前盘后， 是他 settlement price
- Indicative Opening Price 价格
- 盘中，最后成交价格
- 如果都没有 用最后 settlement 价格
- 在市场紧急情况下....
规则：
- 突发情况下， Aarkenstone 可以临时关闭这个规则， 在市场大波动行情下
- 这里参数可以在日内被调整
Market Limit¶
Price Banding 不会限制 market 单子输入， 一个是价单子，仅仅会匹配最后报价， 剩余以limit 进入book。
Stop¶
不会影响， 在输入时候就校验过。
短路设计¶
短路区间根据不同产品，有不同区间， 也可以动态配置。
DCB Dynamic Circuit Breakers:
Formula: Previous Days settle * DCB percentage Value = DCB variant (rounded down to nearest tradable tick)
在市场开盘60分钟内有个回溯窗口， 用来计算最终的上下区间， 最高价格 + 比例作为上区间，最低价格 - 比例最为下区间。
市场和产品状态¶
Market and Instrument States， 包含品类， 和独立产品的状态
| 状态 | 描述 |
|---|---|
| Pre-Open | Earliest phase of Opening market state. Order Entry, modification, and cancel are allowed. No order matching; Mass Quote messages are not allowed. |
| Pre-Open - No Cancel | End of Pre-Open state. Order entry is allowed. Modification and cancellation are not allowed. |
| Opening | Brief intermediate state. Pre-Open orders are resolved following Indicative Opening Price (IOP) determination. Trades are sent. |
| Open | Start of continuous trading phase. Order matching begins. |
| Pause | Interruption of continuous trading. Only order cancellation is allowed. Order matching is not allowed. |
| Close - Not Final | End of day preparation for the next Pre-Open. Not final close for the date. This state allows a mid-session Pre-Open to be initiated. |
| Close - Final | Final Close for the date. Day orders are eliminated. |
| Post - Close | Allows GTC/GTD orders only placement, modification, and cancellation. No matching takes place and no action can be taken on non-GTC/GTD orders. |
| 状态 | 描述 |
|---|---|
| Pre-Open | 市场最早状态,Order Entry, modification, and cancel允许. 尚未匹配; Mass Quote不允许. |
| Pre-Open - No Cancel | End of Pre-Open state. 可以下单, 删除不允许. |
| Opening | Brief intermediate state. Pre-Open orders are resolved following Indicative Opening Price (IOP) determination. Trades are sent. |
| Open | 连续交易开始, 订单匹配开始 |
| Pause | 突发情况下交易终端. 只有单子撤销允许, 订单匹配中断 |
| Close - Not Final | End of day preparation for the next Pre-Open. Not final close for the date. This state allows a mid-session Pre-Open to be initiated. |
| Close - Final | Final Close for the date. Day orders are eliminated. |
| Post - Close | 只有 GTC/GTD orders 可以下，撤销. 订单匹配中断, 非GTC/GTD orders不允许修改 |


Matthew Miracle
Hey guys! My name is Matt. I have been a UC student for 3 years now, and working on a degree in Software Application Development. I gained alot of experience this past semester in my co-op, but admitedly I'll be a little rusty with some of the development tools. I chose this course for two reasons: one, because of my intrest in gamming; and two, because of my interest in development. Gaming is what drew me to IT in the first place, and I've since gravitaed towards the technical world.
As you can tell (Hovering over my picture), My favorite game is Tomb Raider. I'm pretty much into all types of games. Right now, I'm playing lots of diffrent games. To list a few:
- Final Fantasy
- Destiny 2
- Zelda: Breath of the Wild
- Gauntlet
Madgamer09


Pretty full on up front, there is a lot to remember and take in. With the various bookmarks, apps and links one could be forgiven for getting lost. I have asked poor Harrison and Jack so many questions feeling somewhat unsure how to proceed, but I have in many circumstances found the answers for myself very quickly found the answer to the myself the more I explore. Having had some exposure to code some of the programming and coding practices in the past I have found this somewhat beneficial.
I love how open everyone is, and am very impressed with how the Dev Academy has embraced diversity. And the IKE - Integrity, Kindness, Effort.
To know that my study and work environment is going to be engaging, open and regardless of any of my own fears I will be working with an awesome bunch of people.
Honestly, coming into Dev Academy I had no intial pre-concieved notions of what to expect. I enjoy comfort of being supported remotely, I had been worried about how I would manage but all that has been put to rest by the support of Dougal, Jack and knowing that help is available on slack. Slack has defintely made the transition into remote study relatively easy.
Definitely will be a challenge.
Absolutely not it makes me hopeful and positive moving forward.


{% extends "app/layout2.html" %} {% block content %} INVALID REQUEST ID! YOUE COMPLAINT HAS NOT BEEN REGISTERED . {% endblock %}


Thank you for your order and your support! Here is a link to your download page
Please let us know if you need any additional help.
Yours,
Infinite Industries


W0076: Word forms separated by line breaks, which (according to the dictionary) are actually *one* word form -> breaks should be revised and possibly tagged as hyphenation (Umbruch) if the dictionary's guess is correct
Type
Dict. Entry
(Complete)
Dict. Entry
(1)
Dict. Entry
(2)
Lemma(ta)
Freq.
Links
vni | co
vnico
vni
? (co)
?
1
W0076-00-0059-lb-2029
img


Hi there!
I'm Analia, a data-driven, detail-oriented marketer and web developer with a strong understanding of HTML, CSS and Javascript. I also have more than two years of experience in digital marketing, content creation, community building, partner collaborations and customer service.
My résumé and some of my past work can be found below. If you have any questions, please feel free to contact me!
I have worked on a several marketing and web development projects!
Click on the icons below to view some of my past work.


The HighRise™ window cleaning system is the latest innovation from IPC Eagle. IPC Eagle is a leading manufacturer of cleaning equipment and tools throughout the world. This amazing machine offers a safe and effective way of cleaning multi-storey buildings and can be customised to suit specific site requirements.
The major advantage with High-Rise window cleaning is that it offers faster, cleaner and safer window cleaning. Advantages of the High-Rise window cleaning method are:
- Completing a month’s worth of window cleaning in less than a day.
- Safely operated from the top of buildings.
- Cleaning windows and frames.
- Cleaning the entire building for extended life.
- Windows stay cleaner longer with Pure Water.
- Pure Water removes the need to use chemicals.
SELF-CONTAINED/SELF-CLIMBING
The HighRise™ is a completely self-contained and self-climbing window cleaning system that can be operated from existing roof rigs, davit arms, roof cars or portable rigs. Operation is easy through a wireless remote control.


--- layout: page title: About header-img: "img/about-bg.png" ---
Interested in Machine Learning & Deep Learning


When you access a website, the website is very likely made out of three components
JavaScript can change the content and attributes of HTML elements:
console.log()
from
your JavaScript code to display values and messages in the console.Most languages have a set of supported data types. JavaScript supports the following ones:
Number
String
Boolean
null
& undefined
Array
Function
Object
Let's start with numbers.
Remember, in the end, computers are simply blazing fast calculators.
2 + 2;
Some languages distinguish between integer
and real numbers (real numbers are often called
floats
, due to the floating point technique used to represent them).
JavaScript does not make that distinction, everything is a real number (or simply, a Number
).
When explicitly using decimal values, you may experience issues with precision.
Try to work with integers as much as you can, especially when you compare quantities in conditions and loops.
0.1 + 0.2; if (0.1 + 0.2 === 0.3) { console.log("Yes!"); } else { console.log("Oh no, precision issues!"); } if (1 + 2 === 3) { console.log("Yes!"); } else { console.log("Oh no, precision issues!"); }
Strings are simply, a text value.
Calling text values "strings
" may be confusing, but it is a well-established term in Computer Science
that appears in almost every programming language nowadays.
Therefore, we will be using the term string
a lot.
We have three ways for describing strings in JavaScript:
`Using backticks`; "Using doublequotes"; 'Or using singlequotes';
All of them describe a string value.
They have slight differences but nothing to worry about for now.
Use any convention you want, but the backticks (`these ones`
) will let us format our strings later,
so maybe get used to these ones.
Some characters are difficult to write in a string, for one reason or another.
These characters are often escaped with a backslash \
.
A tab is encoded as \t
. A newline is encoded as \n
. In some instances (e.g., in the
terminal of your operating system), a space is escaped as
\
(backslash followed by a space).
You will almost never need to escape a space in JavaScript, but you will need to escape tabs and newlines.
1 or 0. Yes or no. Used a lot to control the flow of programs:
3 > 2; if (301 > 201) { console.log("MUMT 201 is a requirement for MUMT 301"); } else { console.log("MUMT 301 is a requirement for MUMT 201"); }
null
indicates that something deliberately does not have a value.
undefined
indicates that something is uninitialized or undefined.
Don't worry about these for now. You will see later in which cases they show up.
An array is a collection of values.
We denote an array by writing comma-separated values within two square brackets.
["Rhythm guitar", "Lead guitar", "Bass guitar", "Drums", "Vocals"];
Arrays have certain attributes or properties. For example, the
length
, which tells us how many
values are stored in the array.
["Rhythm guitar", "Lead guitar", "Bass guitar", "Drums", "Vocals"]['length'];
We access the attributes of a value using square brackets after the value and referring to the attribute's name.
If the attribute name meets the rules of valid identifiers, they can also be accessed using a period after the value, followed by the name of the attribute.
["Rhythm guitar", "Lead guitar", "Bass guitar", "Drums", "Vocals"].length;
Other datatypes also have attributes. They are not exclusive of arrays.
For example, Strings
have a startsWith
attribute to verify whether they start with a
given substring.
function addition (a, b) { return a + b; } addition(2, 2);
You can think of functions in several ways:
In practice, JavaScript functions are more complex than this, however, we can assume this is how they operate for now.
Objects store information in key: value
pairs of values.
They are very useful to organize information in intuitive ways.
let guitar = { model: "Soloist", brand: "Jackson", year: 2016, frets: 24 };
Each of the fields can be accessed as an attribute:
console.log(guitar['brand']);
And new attributes can be added too:
guitar.pickups = "Dimarzio Black Winter";
Notice that the fields could be of different data types:
typeof(guitar.pickups); typeof(guitar.frets);
We store values in variables.
There are three words that we use to declare variables:
let x = 5; const y = 5; var z = 5;
We will mostly use let
.
const
is used for assigning values that you don't expect will change.
var
is there for backward compatibility with older JavaScript versions.
It's almost identical to let
.
let mouse = "mickey"; console.log(mouse);
We can reassign the variable to a different value (except for constants declared using const
).
mouse = 1; console.log(mouse);
Notice that
console.log(mouse);
is different than
console.log("mouse");
This is because the variable mouse
is not a value, it is a named reference to a value.
What if we try this one:
console.log(duck);
It doesn't exist. But we can make it exist
let duck = "donald"; console.log(duck);
We already used a variable for storing the guitar
object.
We can really store any data type in a variable:
Numbers
Strings
Booleans
Arrays
Objects
Functions
When we run computer code, we can decide to go through one branch of code or another one.
In order to control the flow, we use the conditional statements if
and else
:
function noteSpelling(inputNote) { if (inputNote === 'F#') { console.log('This is an F sharp.'); } else if (inputNote === 'Gb') { console.log('This is a G flat.'); } else { console.log('Sorry, I only know F sharps and G flats.'); } } let note = 'F#'; noteSpelling(note); note = 'Gb'; noteSpelling(note); note = 'C#'; noteSpelling(note);
Beside conditions, another common operation to control the flow of the program is doing loops.
There are three ways of achieving this in JavaScript:
for
loopswhile
loopsdo while
loopsIn general terms, you can achieve exactly the same operation using either of them.
Some of them are simply more convenient in certain scenarios.
Here is a while
loop:
const ageLimit = 18; let myAge = 0; while (myAge < ageLimit) { console.log(`You are ${myAge} years old.  You can drink now. Welcome.`);
This is the equivalent code using a for
loop:
const ageLimit = 18; for (var myAge = 0; myAge < ageLimit; myAge++) { console.log(`You are ${myAge} years old.  You can drink now. Welcome.`);
You can read more about for
loops here.
JavaScript can be used to execute code when events are detected
These events are actions that happen to HTML elements. For example:
<element onload="myScript()">
<select onchange="myFunction()">
<button type="button" onclick=otherScript()>
Click the button to display how many minutes there are left to finish this class
The list of possible events can be found here
script
tag
Embedding code inside an html file
Remember the style
tag and how we used it to add CSS to our HTML website?
The equivalent for javascript is the script
tag.
script
tag contain JavaScript code, and the browser will interpret the code
between them as such.body
section of a web page can reduce display time..js
. To use an external script, put the name of the
script
file in the source (src) attribute of the script
tag:<script src="myScript.js"></script>
The Document Object Model (DOM) is a platform and language-neutral interface that allows programs and scripts to dynamically access and update the content, structure, and style of a document.
You can access your HTML document within JavaScript through the document
object.
You can think of document
as a variable that is already given to you,
and it provides access to your HTML elements.
With it, you can select elements from the DOM, change their attributes, and append new elements to it.
function domExample() { let aButton = document.getElementById("domButton"); aButton.classList.add("primary"); aButton.innerHTML = "I clicked it!"; }
For example, when the button below is linked to the domExample()
function.
It will run its JavaScript code.
The button is defined in the following way
<button id="domButton" class="button" onclick="domExample()">Example</button>
Let's apply the concepts we learned to create a table at the end of this document.
We will use an Array
of Objects
to store (a portion of) the discography of The Beatles.
The fields of each Object
contain either String
or Number
values.
Each Object
will be a row in the table, and all the rows (Objects
) live
inside an Array
.
In JavaScript, the data looks like this:
let beatles_releases = [{ 'album': 'Please Please Me', 'year': 1963, 'label': "Parlophone" }, { 'album': 'With the Beatles', 'year': 1963, 'label': "Parlophone" }, { 'album': 'Introducing... The Beatles', 'year': 1964, 'label': "Vee-Jay Records" }, { 'album': 'Meet the Beatles', 'year': 1964, 'label': "Capitol Records" }, { 'album': 'Twist and Shout', 'year': 1964, 'label': "Capitol Records" }, { 'album': "The Beatles' Second Album", 'year': 1964, 'label': "Capitol Records" }, { 'album': "The Beatles' Long Tall Sally", 'year': 1964, 'label': "Capitol Records" }, { 'album': "Revolver", 'year': 1966, 'label': "EMI" }]
We will iterate through them using a for
loop to generate the rows of a table
element
in HTML.
The table
element does not exist yet!
We will attach it to a container element with an id="discography_table"
.
The container element is the last html element of this file, before the script
tag
with all the JavaScript code that we have been using so far.
You cannot see the container element, however, after you press the button, our loop will populate it with our new table.
Here is the code responsible for creating and filling up the table.
function discography() { let table = document.createElement('table'); table.id = "beatles_table" for (row = 0; row < beatles_releases.length; row++) { tr = document.createElement('tr'); let release_data = Object.keys(beatles_releases[row]); for (col = 0; col < Object.keys(beatles_releases[row]).length; col++) { td = document.createElement('td'); tr.appendChild(td); td.innerHTML = beatles_releases[row][release_data[col]]; } table.appendChild(tr); } document.getElementById("discography_table").appendChild(table); }


By Chen Hui Jing / @hj_chen
Grid Layout is a new layout model for CSS that has powerful abilities to control the sizing and positioning of boxes and their contents.
Unlike Flexible Box Layout, which is single-axis–oriented, Grid Layout is optimized for 2-dimensional layouts.
Source: CSS Grid Layout Module Level 1Gecko: intent to ship in Firefox 52 (7 March, 2017)
Blink: intent to ship in Chrome 57 (14 March, 2017)
Webkit: ships in Safari 10.1 (release date March/April-ish)
Edge: on the backlog with High priority 🤷
Enable the flag called Enable experimental Web Platform features going to:
chrome://flags/#enable-experimental-web-platform-features
Enable the flag called layout.css.grid.enabled going to:
about:config
Enable the flag called Enable experimental Web Platform features going to:
opera://flags/#enable-experimental-web-platform-features
In Safari Technology Preview and WebKit Nightly Builds you can enable the experimental feature called CSS Grid using the menu: Develop > Expermiental Features > CSS Grid
Set the environment variable
WEBKITGTK_EXPERIMENTAL_FEATURES
:
$ export WEBKITGTK_EXPERIMENTAL_FEATURES="CSS_GRID_LAYOUT=1"
CSS Writing Modes Level 3 defines CSS features to support for various international writing modes, such as left-to-right (e.g. Latin or Indic), right-to-left (e.g. Hebrew or Arabic), bidirectional (e.g. mixed Latin and Arabic) and vertical (e.g. Asian scripts).
You can make your browser literally turn on its side from left-to-right.
🙃Or make it read from right-to-left.
🙂Vertical text is fun!
Centring things is no fun
See the Pen Vertical layout behaviour by Chen Hui Jing (@huijing) on CodePen.
margin-top: auto;
margin-bottom: auto;
Browser support: CSS Writing Mode
Can I Use css-writing-mode? Data on support for the css-writing-mode feature across the major browsers from caniuse.com.
Introduces logical properties and values that provide the author with the ability to control layout through logical, rather than physical, direction and dimension mappings.
Source: CSSWGstart
and end
vs. left
and right
Browser support: CSS Logical Properties
Can I Use css-logical-props? Data on support for the css-logical-props feature across the major browsers from caniuse.com.
Disclaimer: If you're reading this from the future, maybe can.Disclaimer: you cannot learn CSS grid overnight.
It'd be nice if you read the specification 🤓
| Grid container | Grid item |
|---|---|
|
|
.container {
display: grid;
grid-column-gap: 1em;
grid-row-gap: 1em;
}
.top-left {
grid-row: 1 / 2;
grid-column: 1 / 2;
align-self: center;
justify-self: end;
}
.top-right {
grid-row: 1 / 2;
grid-column: 2 / 3;
align-self: center;
justify-self: start;
}
.bottom {
grid-column: 1 / 3;
grid-row: 2 / 3;
justify-self: center;
}
fr
→ represents a fraction of the free space in the grid container.
.container {
display: grid;
grid-template-columns: 3.6em 1fr;
grid-column-gap: 0.5em;
grid-row-gap: 1em;
}
.left {
grid-row: 1 / 2;
align-self: center;
}
.top-right {
grid-row: 1 / 2;
grid-column: 2 / 3;
align-self: center;
justify-self: start;
}
.bottom {
grid-column: 1 / 3;
grid-row: 2 / 3;
justify-self: center;
}
repeat()
→ represents a repeated fragment of the track list
.outer-container {
display: grid;
grid-template-columns: 1fr 2em;
}
.inner-container {
grid-column: 1 / 2;
grid-row: 1 / 2;
display: grid;
grid-column-gap: 0.5em;
grid-row-gap: 1em;
@media all and (max-width: 719px) {
grid-template-columns: repeat(2, 1fr);
}
@media all and (min-width: 720px) and (max-width: 1279px) {
grid-template-columns: repeat(3, 1fr);
}
@media all and (min-width: 1280px) {
grid-template-columns: repeat(4, 1fr);
}
}
.right {
align-self: center;
grid-column: 2 / 3;
grid-row: 1 / 2;
}


The fight broke out Tuesday afternoon on a BART train pulling into a station in Hayward.
The San Francisco Chronicle says police are looking into whether the victim was a good Samaritan who tried to stop the suspect from stealing items from another person, possibly shoes.
The man ran from the station. The Chronicle says he was arrested a block away after employees of a car dealership said he tried to steal a van.
Employee Steve Castro tells the paper that he fought with the shirtless man, who snatched the keys from his hand as he was showing the van to a customer.
4:14 p.m.
A California transit chief says a man has been stabbed to death on a San Francisco Bay Area commuter train during a fight.
Interim BART Police Chief Ed Alvarez told reporters at a news conference that officials began receiving 911 calls Tuesday afternoon about a fight aboard a train between two men.
He says transit officers boarded the train at the next stop and found a man bleeding, who was possibly the victim of a stabbing. He says the man died.
Alvarez says transit officers quickly searched the area and were able to apprehend a suspect.
He said there is no threat to the public because it was a fight between two people who engaged each other.
Officials did not immediately provide any other details.
Sign up for Daily Newsletters
Copyright © 2019 The Washington Times, LLC.
Please read our comment policy before commenting.


The regular expression can be something like :
/name=[^>]*\.(bat|cmd|exe|com|pif|reg|scr|vb|vbe|vbs)/
to match attachments whose filenames end with extensions signifying potentially dangerous Windows executables.
The action can be like :
REJECT
to simply reject mail matching the expression, or :
REDIRECT<EMAIL_ADDRESS>To forward mail to another address.


SAP Section 2: Ventilation¶
SAP Section 2: Ventilation¶
Configure the ventilation according to section 2 of SAP
-
sap.ventilation.
configure_ventilation
(dwelling)[source]¶ Mechanical ventilation:
Positive input ventilation (PIV) Positive input ventilation is a fan driven ventilation system, which often provides ventilation to the dwelling from the loft space. The SAP calculation procedure for systems which use the loft to pre-heat the ventilation air is the same as for natural ventilation, including 20 m3/h ventilation rate equivalent to two extract fans or passive vents. (The energy used by the fan is taken as counterbalancing the effect of using slightly warmer air from the loft space compared with outside). Some positive input ventilation systems supply the air directly from the outside and the procedure for these systems is the same as for mechanical extract ventilation.
Mechanical extract ventilation (MEV) MEV is a fan driven ventilation system, which only extracts air from the dwelling. The SAP calculation is based on a throughput of 0.5 air changes per hour through the mechanical system, plus infiltration. MEV can be either:
- centralised: air is extracted from wet rooms via ducting and expelled by means of a central fan., or
- decentralised: air is extracted by continuously-running fans in each wet room.
Parameters: dwelling – Returns:


Protocols
The following protocols are available globally.
-
The
See moreContextProtocol
protocol exposes the methods and properties of an underlyingcairo_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeContext
. Alternatively, useContextRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol ContextProtocol
-
The
See moreDeviceProtocol
protocol exposes the methods and properties of an underlyingcairo_device_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeDevice
. Alternatively, useDeviceRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol DeviceProtocol
-
The
See moreSurfaceProtocol
protocol exposes the methods and properties of an underlyingcairo_surface_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeSurface
. Alternatively, useSurfaceRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol SurfaceProtocol
-
The
See moreMatrixProtocol
protocol exposes the methods and properties of an underlyingcairo_matrix_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeMatrix
. Alternatively, useMatrixRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol MatrixProtocol
-
The
See morePatternProtocol
protocol exposes the methods and properties of an underlyingcairo_pattern_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seePattern
. Alternatively, usePatternRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol PatternProtocol
-
The
See moreRegionProtocol
protocol exposes the methods and properties of an underlyingcairo_region_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeRegion
. Alternatively, useRegionRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol RegionProtocol
-
The
See moreFontOptionsProtocol
protocol exposes the methods and properties of an underlyingcairo_font_options_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeFontOptions
. Alternatively, useFontOptionsRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol FontOptionsProtocol
-
The
See moreFontFaceProtocol
protocol exposes the methods and properties of an underlyingcairo_font_face_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeFontFace
. Alternatively, useFontFaceRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol FontFaceProtocol
-
The
See moreScaledFontProtocol
protocol exposes the methods and properties of an underlyingcairo_scaled_font_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeScaledFont
. Alternatively, useScaledFontRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol ScaledFontProtocol
-
The
See morePathProtocol
protocol exposes the methods and properties of an underlyingcairo_path_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seePath
. Alternatively, usePathRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol PathProtocol
-
The
See moreRectangleProtocol
protocol exposes the methods and properties of an underlyingcairo_rectangle_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeRectangle
. Alternatively, useRectangleRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol RectangleProtocol
-
The
See moreRectangleIntProtocol
protocol exposes the methods and properties of an underlyingcairo_rectangle_int_t
instance. The default implementation of these can be found in the protocol extension below. For a concrete class that implements these methods and properties, seeRectangleInt
. Alternatively, useRectangleIntRef
as a lighweight,unowned
reference if you already have an instance you just want to use.Declaration
Swift
public protocol RectangleIntProtocol


So, you think you want to start mountain biking? Welcome to the fun side!
Ready to start mountain biking, but don't know really where to start? What you'll need? How to maintain your equipment? Oh, and maybe some tips on basic riding skills? Don't fret, we've got you covered.
If you're interested in further research, resources, tools, and well, just cool bike stuff we recommend visiting Park Tool. They have a large breadth of tips and tricks for bike maintenance. Not to mention, their site is easy and fun to navigate through. I recognize block elements and a lot of attributes, but I don't recognize the CSS styling and code for that yet.


Suppose we have several versions of the same module (for
example the
How can we make sure that moudle names don't collide? In Erlang module names must be unique. Ho can two independentally developed program guyarantee that the modukles names they use don't collide?
How can we be sure that
On some date we tested some partticular collection of modules and something went wrong. We want to report a bug. How can we make sure that we can precisely identifcy exactly whhich modue were used so that the bug can be reproduced?
We propose some new annotations what can be used to precisely identify a moduke and its prove authorship of the module.
We'll start with an example. Alice starts by writing the module
-module(foo). -export([a/1]). %% Version$author:Alice$ %% Version$end$ a(X) -> Y = lists:reverse(X), foo:baz(Y).
Alice tests her program and wishes to publish the program. She
gives the shell command
-module(foo). -export([a/1]). %% Version$author:Alice$ %% Do not edit the Version Block By Hand -version(lists,"a23545f1acd365231626217365bcad2"). -version(foo, "a23545f1acd365231626217365bcad2"). -version(foo, "623547254726547254725472574527"). -author(foo,alice,"1625371537136512436143654"). %% Version$end$ a(X) -> Y = lists:reverse(X), foo:baz(Y).
The annotatiion
When this module is now compiled the compiler will compile the code as if Aliuce had written:
-module(foo). -export([a/1]). a(X) -> Y = 'a23545f1acd365231626217365bcad2':reverse(X), '623547254726547254725472574527':baz(Y).
And instead of producing
The first stup is to create a “name map” of all the files in the current directory:
> elib1_publish:publish(). [elib1_lin,elib1_rsa,io_lib_pretty,filelib]
This lists the files which have been added to the name map. The
name map is stored in a file called
-module(nmap). %% autogenerated do not edit by hand. -export([map/0]). map()-> [{elib1_lin,"elib1_lin.erl","joe", mBA4EEB84C7300F1E41DBA739A5B6B5CD,<PHONE_NUMBER>449511917694936...}, {elib1_publish,"elib1_publish.erl","joe", m82025D6B593F591DCA2C22A7B43DB6EC,<PHONE_NUMBER>5546639274897433290083170...}, ... ].
the name mape is a list of
Is a module name
Is the file name of the file containing the module
Is the name of the person signig the module
Is an atom containing an imbedded MD5 checkum of the
contents of
Is the RSA digital signature of
the Md5 checksum signed with
> elib1_publish:compile(). creating:"mBA4EEB84C7300F1E41DBA739A5B6B5CD.beam" creating:"m82025D6B593F591DCA2C22A7B43DB6EC.beam" creating:"m79D5C6A6F882B11991744F7B2606CA64.beam" creating:"m446C085CB7758C195CF3CF95B16C9DB0.beam" creating:"m07A010C6CA0E9A4140EBA235E724F77A.beam"
Once we have a name map we can transform all the erlang in the current directory into an equivalent set of modules where all the module names have bee replaced by the MD5 sums of the content of the original source code files containing the modules.
Everythjing remains consistent, providing we can call
This means that the md5 checksum of x1.erl is m273 .... and 2135... is the MD5 sum signed with joe's public key
transform all code in x1.erl x2.erl replacing the module names x1, x2 ... etc. with the MD5 sums so x1:abc(...) becomes m273...:abc( ...)
replace apply(M,F,A) with newapply(map(),M, F, A)
result - a) no name space collisions b) exact version control c) safety (if you can't guess the MD5 sum :-)
It's kind of like adding a big "where" clause round a module
-module(foo). a() -> lists:reverse(...) WHERE foo = m1283abcd ... lists = m34aefg ...
ie all modules names are converted to the MD5 sums of the original sources.
This is used to solve a lot of problems with safety, versioning, testing, namespaces etc.
(safe erlang can be made by replacing calls to dangerous mods like file etc. with safe_file ... etc.)


Use this form to upload one or more faults that are already in Disloc input file format. The following example shows formatting:
| Project Name | {{myproject.projectName}} |
| Project ID | {{myproject._id}} |
| Input File | {{myproject.projectInputFileName}} |
| Parameters |
|
| Output File | {{myproject.projectOutputFileName}} |
| Output KML | {{myproject.projectOutputKMLFileName}} |
| SARImage KML | {{myproject.projectOutputSARImageKMLFileName}} |
| Download All | {{myproject.projectZipFileName}} |
| Status | {{myproject.status}} |


Displays the number of NFS calls that were responded to remotely (that is, calls that traversed the WAN to the NFS server). Displays the delayed calls that were responded to locally but not immediately (for example, reads that were delayed while a read ahead was occurring and that were responded to from the data in the read ahead).How many NFS calls were answered locally and remotely? How many delayed responses occurred for NFS activity? Use the mouse to hover over a specific data point to see what the y values and exact timestamp were in relation to peaks.The Riverbed system reports on performance for periods up to one month. Due to performance and disk space considerations, the display granularity decreases with time passed since the data was sampled. The data is collected at a 5-minute granularity for the entire month.
Select a report time interval of 5 minutes (5m), 1 hour (1h), 1 day (1d), 1 week (1w), All, or type a custom date. All includes statistics for the last 30 days.You can view the newest data and see data points as they are added to the chart dynamically. To display the newest data, click Show newest data.


// Schedule an event to fire at a specific date/time Schedule.On(DateRules.On(2013, 10, 7), TimeRules.At(13, 0), () => Log($"SpecificTime: Fired at : {Time}")); // Schedule an event to fire every trading day for a security // The time rule here tells it to fire at 13:00:00 UTC Schedule.On(DateRules.EveryDay("SPY"), TimeRules.At(13, 0, 0, TimeZones.Utc), () => Log($"EveryDay.SPY SpecificTime: Fired at: {Time}")); // Schedule an event to fire every trading day for a security // The time rule here tells it to fire 10 minutes after SPY's market open Schedule.On(DateRules.EveryDay("SPY"), TimeRules.AfterMarketOpen("SPY", 10), () => Log($"EveryDay.SPY 10 min after open: Fired at: {Time}")); // Schedule an event to fire every trading day for a security // The time rule here tells it to fire 10 minutes before SPY's market close Schedule.On(DateRules.EveryDay("SPY"), TimeRules.BeforeMarketClose("SPY", 10), () => Log($"EveryDay.SPY 10 min before close: Fired at: {Time}")); // Schedule an event to fire on certain days of the week Schedule.On(DateRules.Every(DayOfWeek.Monday, DayOfWeek.Friday), TimeRules.At(12, 0), () => Log($"Mon/Fri at 12pm: Fired at: {Time}")); // Schedule an event to fire once today at when this method is called (now) Schedule.On(DateRules.Today, TimeRules.Now, () => Log($"Now: Fired at: {Time}")); // Schedule an event to fire once tomorrow at midnight Schedule.On(DateRules.Tomorrow, TimeRules.Midnight, () => Log($"Tomorrow at midnight: Fired at: {Time}")); // Schedule an event to fire once today at noon Schedule.On(DateRules.Today, TimeRules.Noon, () => Log($"Today at noon: Fired at: {Time}")); // The scheduling methods return the ScheduledEvent object which can be used // for other things here I set the event up to check the portfolio value every // 10 minutes, and liquidate if we have too many losses Schedule.On(DateRules.EveryDay(), TimeRules.Every(TimeSpan.FromMinutes(10)), LiquidateUnrealizedLosses); // Schedule an event to fire at the beginning of the month, the symbol is optional. // if specified, it will fire the first trading day for that symbol of the month, // if not specified it will fire on the first day of the month Schedule.On(DateRules.MonthStart("SPY"), TimeRules.AfterMarketOpen("SPY"), RebalancingCode); // Schedule an event to fire at the end of the month, the symbol is optional. // if specified, it will fire the last trading day for that symbol of the month, // if not specified it will fire on the first day of the month Schedule.On(DateRules.MonthEnd("SPY"), TimeRules.BeforeMarketClose("SPY"), RebalancingCode); // Schedule an event to fire at the beginning of the week, the symbol is optional. // if specified, it will fire the first trading day for that symbol of the week, // if not specified it will fire on the first day of the week Schedule.On(DateRules.WeekStart("SPY"), TimeRules.AfterMarketOpen("SPY", 5), RebalancingCode); // Schedule an event to fire at the end of the week, the symbol is optional. // if specified, it will fire the last trading day for that symbol of the week, // if not specified it will fire on the first day of the week Schedule.On(DateRules.WeekEnd("SPY"), TimeRules.BeforeMarketClose("SPY", 5), RebalancingCode); // The following methods are not defined in Initialize: private void LiquidateUnrealizedLosses() { // if we have over 1000 dollars in unrealized losses, liquidate if (Portfolio.TotalUnrealizedProfit < -1000) { Log($"Liquidated due to unrealized losses at: {Time}"); Liquidate(); } } private void RebalancingCode() { // Good spot for rebalancing code? }
# Schedule an event to fire at a specific date/time self.Schedule.On(self.DateRules.On(2013, 10, 7), self.TimeRules.At(13, 0), lambda: self.Log(f"SpecificTime: Fired at : {self.Time}")) # Schedule an event to fire every trading day for a security the # The time rule here tells it to fire at 13:00:00 UTC self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(13, 0, 0, TimeZones.Utc), lambda: self.Log(f"EveryDay.SPY SpecificTime: Fired at: {self.Time}")) # Schedule an event to fire every trading day for a security the # The time rule here tells it to fire 10 minutes after SPY's market open self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 10), lambda: self.Log(f"EveryDay.SPY 10 min after open: Fired at: {self.Time}")) # Schedule an event to fire every trading day for a security the # The time rule here tells it to fire 10 minutes before SPY's market close self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 10), lambda: self.Log(f"EveryDay.SPY 10 min before close: Fired at: {self.Time}")) # Schedule an event to fire on certain days of the week self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Friday), self.TimeRules.At(12, 0), lambda: self.Log(f"Mon/Fri at 12pm: Fired at: {self.Time}")) # Schedule an event to fire once today at when this method is called (now) self.Schedule.On(self.DateRules.Today, self.TimeRules.Now, lambda: self.Log(f"Now: Fired at: {self.Time}")) # Schedule an event to fire once tomorrow at midnight self.Schedule.On(self.DateRules.Tomorrow, self.TimeRules.Midnight, lambda: self.Log(f"Tomorrow at midnight: Fired at: {self.Time}")) # Schedule an event to fire once today at noon self.Schedule.On(self.DateRules.Today, self.TimeRules.Noon, lambda: self.Log(f"Today at noon: Fired at: {self.Time}")) # the scheduling methods return the ScheduledEvent object which can be used # for other things here I set the event up to check the portfolio value every # 10 minutes, and liquidate if we have too many losses self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(timedelta(minutes=10)), self.LiquidateUnrealizedLosses) # Schedule an event to fire at the beginning of the month, the symbol is optional. # if specified, it will fire the first trading day for that symbol of the month, # if not specified it will fire on the first day of the month self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY"), self.RebalancingCode) # Schedule an event to fire at the end of the month, the symbol is optional. # if specified, it will fire the last trading day for that symbol of the month, # if not specified it will fire on the first day of the month self.Schedule.On(self.DateRules.MonthEnd("SPY"), self.TimeRules.BeforeMarketClose("SPY"), self.RebalancingCode) # Schedule an event to fire at the beginning of the week, the symbol is optional. # if specified, it will fire the first trading day for that symbol of the week, # if not specified it will fire on the first day of the week self.Schedule.On(self.DateRules.WeekStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 5), self.RebalancingCode) # Schedule an event to fire at the end of the week, the symbol is optional. # if specified, it will fire the last trading day for that symbol of the week, # if not specified it will fire on the first day of the week self.Schedule.On(self.DateRules.WeekEnd("SPY"), self.TimeRules.BeforeMarketClose("SPY", 5), self.RebalancingCode) # The following methods are not defined in Initialize: def LiquidateUnrealizedLosses(self) -> None: ''' if we have over 1000 dollars in unrealized losses, liquidate''' if self.Portfolio.TotalUnrealizedProfit < -1000: self.Log(f"Liquidated due to unrealized losses at: {self.Time}") self.Liquidate() def RebalancingCode(self) -> None: ''' Good spot for rebalancing code?''' pass


CATS Logo
(current)
Email
Text Messages
Messages
Home
Profile
Personal Info
Logout
Recruiting
(current)
Tasks
Interview
Call
Review
Jobs
Candidates
Profiles & Resumes
Analytics
Onboarding
Tasks
Candidates
Onboarding
HR
Contacts
Help
Security Settings
Dashboard
Personalization


CASE STUDIES
This is an example of a portfolio gallery. It has some simple hover transitions and is pretty rad.
Developing Hexxis
View Case Study
Developing Hexxis
View Case Study
Developing Hexxis
View Case Study
Developing Hexxis
View Case Study
Developing Hexxis
View Case Study
Developing Hexxis
View Case Study