4 Intro Centering and Scaling Example: Reading Achievement (2-levels only)
library(tidyverse) # all things tidy
library(haven) # read in SPSS dataset
library(furniture) # nice table1() descriptives
library(stargazer) # display nice tables: summary & regression
library(texreg) # Convert Regression Output to LaTeX or HTML Tables
library(psych) # contains some useful functions, like headTail
library(sjstats) # ICC calculations
library(effects) # Effects for regression models
library(optimx) # Different optimizers to solve mlm's
library(lme4) # non-linear mixed-effects models
library(haven) # read in SPSS dataset
4.1 Background
The following example was included in the text “Multilevel Modeling in R” by Finch, Bolin, and Kelley (2016).
The datasets for this textbook may be downloaded from the website: http://www.mlminr.com/data-sets/.
I was unable to find any documentation on this dataset in the book or online, so I contacted the authors. There were unable to provide much either, but based on visual inspection designated the class of factor to thoes vairables that seem to represent categorical quantities. The labels for gender and class size are relative to the frequencies in the journal article the authors did point me to (although the samples sizes do not match up).
FOR THIS CHAPTER WE WILL IGNORE ALL LEVELS EXCEPT FOR STUDNETS BEING NESTED WITHIN SCHOOLS.
Read the SPSS data in with the haven
package .
data_raw <- haven::read_sav("http://www.mlminr.com/data-sets/Achieve.sav?attredirects=0")
Declare all categorical variables to be factors and apply labels where meaningful.
Student-specific
*gender
= Male or Female
*age
= Age, in months
*gevocab
= Vocabulary Score
*geread
= Reading Score
Class-specific
*classsize
= category of class’s size
School-specific
*senroll
= school enrollment
*ses
= school’s SES level
data_achieve <- data_raw %>%
dplyr::mutate_at(vars(id, region, corp, school, class), factor) %>%
dplyr::mutate(gender = gender %>%
factor(labels = c("Female", "Male"))) %>%
dplyr::mutate(classize = classize %>%
factor(labels = c("12-17", "18-21",
"22-26", ">26"))) %>%
dplyr::select(id, region, corp, school, class, # Identifiers
gender, age, geread, gevocab, # Pupil-level vars
classize, # Class-Level vars
senroll, ses) # School-level vars
4.1.1 Sample Structure
It is obvious that the sample is hiarchical in nature. The nesting starts with students
(level 1) nested within class
(level 2), which are further nested within school
(level 3), corp
(level 4), and finally region
(level 5).
For this chapter we will only focus on TWO levels: students (level 1) are the units on which the outcome is measured and schools (level 2) are the units in which they are nested.
The number of regions = 9:
num_regions <- data_achieve %>%
dplyr::group_by(region) %>%
dplyr::tally() %>%
nrow()
num_regions
[1] 9
The number of corps = 60:
num_corps <- data_achieve %>%
dplyr::group_by(region, corp) %>%
dplyr::tally() %>%
nrow()
num_corps
[1] 60
The number of schools = 160
num_schools <- data_achieve %>%
dplyr::group_by(region, corp, school) %>%
dplyr::tally() %>%
nrow()
num_schools
[1] 160
The number of classes = 568
num_classes <- data_achieve %>%
dplyr::group_by(region, corp, school, class) %>%
dplyr::tally() %>%
nrow()
num_classes
[1] 568
The number of students = 10320
num_subjects <- data_achieve %>% nrow
num_subjects
[1] 10320
4.2 Exploratory Data Analysis
4.2.1 Summarize Descriptive Statistics
<IP_ADDRESS> The stargazer
package
Most posters, journal articles, and reports start with a table of descriptive statistics. Since it tends to come first, this type of table is often refered to as Table 1. The stargazer()
function can be used to create such a table, but only for the entire dataset. I haven’t been able to find a way to get it to summarize subsamples and compare them in the standard format. Also, it only summarises continuous, not categorical variables.
# Knit to Website: type = "html"
# Knit to PDF: type = "latex"
# View on Screen: type = "text"
data_achieve %>%
dplyr::select(classize, gender, geread, gevocab, age, ses, senroll) %>%
data.frame() %>%
stargazer::stargazer(header = FALSE,
title = "Summary of the numeric variables with `stargazer`",
type = "html")
| Statistic | N | Mean | St. Dev. | Min | Pctl(25) | Pctl(75) | Max |
| geread | 10,320 | 4.341 | 2.332 | 0.000 | 2.800 | 4.900 | 12.000 |
| gevocab | 10,320 | 4.494 | 2.368 | 0.000 | 2.900 | 5.200 | 11.200 |
| age | 10,320 | 107.529 | 5.060 | 82 | 104 | 111 | 135 |
| ses | 10,320 | 72.849 | 21.982 | 0.000 | 66.300 | 87.800 | 100.000 |
| senroll | 10,320 | 533.415 | 154.797 | 115 | 438 | 644 | 916 |
<IP_ADDRESS> The furniture
package
Tyson Barrett’s furniture package includes the extremely useful function table1()
which simplifies the common task of creating a stratified, comparative table of descriptive statistics. Full documentation can be accessed by executing ?furniture::table1
.
# Knit to Website: output = "html"
# Knit to PDF: output = "latex2"
# View on Screen: output = ""text", or "markdown", "html"
data_achieve %>%
furniture:: table1("Reading Score" = geread,
"Vocabulary Score" = gevocab,
"Age (in months)" = age,
"School SES" = ses,
"School's Enrollment" = senroll,
splitby = ~ gender, # var to divide sample by
test = TRUE, # test groups different?
caption = "Summary of the numeric variables with `table1`",
output = "html")
| Female | Male | P-Value | |
|---|---|---|---|
| n = 5143 | n = 5177 | ||
| Reading Score | 0.218 | ||
| 4.4 (2.3) | 4.3 (2.3) | ||
| Vocabulary Score | <.001 | ||
| 4.6 (2.4) | 4.4 (2.3) | ||
| Age (in months) | <.001 | ||
| 107.1 (5.0) | 107.9 (5.1) | ||
| School SES | 0.155 | ||
| 72.5 (22.3) | 73.2 (21.7) | ||
| School’s Enrollment | 0.483 | ||
| 532.3 (154.5) | 534.5 (155.1) |
4.2.2 Visualization of Raw Data
<IP_ADDRESS> Level One Plots: Disaggregate or ignore higher levels
For a first look, its useful to plot all the data points on a single scatterplot as displayed in the previous plot. Due to the large sample size, many points end up being plotted on top of or very near each other (overplotted). When this is the case, it can be useful to use geom_binhex()
rather than geom_point()
so the color saturation of the hexigons convey the number of points at that location, as seen in Figure .
Note: I had to manually install the package hexbin
for the geom_hex()
to run.
data_achieve %>%
ggplot() +
aes(x = gevocab,
y = geread) +
stat_binhex(colour = "grey85", na.rm = TRUE) + # outlines
scale_fill_gradientn(colors = c("grey80","navyblue"), # fill color extremes
name = "Frequency", # legend title
na.value = NA) + # color for count = 0
theme_bw()
<IP_ADDRESS> Multilevel plots: illustrate two nested levels
Up to this point, all investigation of this dataset has been only at the pupil level and any nesting or clustering within schools has been ignored. Plotting is a good was to start to get an idea of the school-to-school variability. This figure displays four handpicked school to illustrate the degreen of school-to-school variability in the association between vocab and reading scores.
data_achieve %>%
dplyr::filter(school %in% c(1321, 6181,
6197, 6823)) %>% # choose school numbers
ggplot(aes(x = gevocab,
y = geread))+
geom_count() + # creates points, size by overplotted number
geom_smooth(method = "lm") + # linear model (OLS)
facet_wrap(~ school) + # panels by school
theme_bw()
Another way to explore the school-to-school variability is to plot the linear model fit independently to each of the schools. This next figure displays only the smooth lines without the standard error bands or the raw data in the form of points or hexagons.
data_achieve %>%
ggplot(aes(x = gevocab,
y = geread)) +
geom_smooth(aes(group = school),
method = "lm",
se = FALSE, # do NOT want the SE bands
size = 0.3) +
geom_smooth(method = "lm",
se = FALSE,
color = "red", # do NOT want the SE bands
size = 2) + # make the lines thinner
theme_bw()
Due to the high number of schools, the figure with all the school’s independent linear regression lines resembles a hairball and is hard to deduce much about individual schools. By using the facet_grid()
layer, we can seperate the schools out so better see school-to-school variability. It also allows investigation of higher level predictors, such as the school’s SES (median split with ntile(var, 2)
) and class size.
data_achieve %>%
dplyr::mutate(ses2 = ntile(ses, 2) %>% # median split
factor(labels = c("SES: Lower Half",
"SES: Upper Half"))) %>%
dplyr::mutate(senroll = ntile(senroll, 3) %>%
factor(labels = c("Enroll: Smallest Third",
"Enroll: Middle Third",
"Enroll: Largest Third"))) %>%
ggplot(aes(x = gevocab,
y = geread,
group = school)) + # sepearates students into schools
geom_smooth(method = "lm",
se = FALSE,
size = 0.3,
color = "black",
alpha = .2) +
theme_bw() +
facet_grid(senroll ~ ses2) # makes seperate panels (rows ~ columns)
4.3 Single-Level Regression
4.3.1 Fit Nested Models
Ignoring the fact that students are nested or clustered within schools, is called dissagregating. This treats all students as independent units.
# linear model - ignores school (for reference only)
fit_read_lm_0 <- lm(formula = geread ~ 1, # intercept only
data = data_achieve)
fit_read_lm_1 <- lm(formula = geread ~ gevocab , # one predictor
data = data_achieve)
fit_read_lm_2 <- lm(formula = geread ~ gevocab + age, # two predictors
data = data_achieve)
fit_read_lm_3 <- lm(formula = geread ~ gevocab*age, # interation+main effects
data = data_achieve)
Now compare the models:
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_lm_0,
fit_read_lm_1,
fit_read_lm_2,
fit_read_lm_3),
custom.model.names = c("Null",
"1 IV",
"2 IV",
"Interaction"),
caption = "OLS: Investigate Fixed, Pupil-level Predictors",
caption.above = TRUE,
single.row = TRUE)
| Null | 1 IV | 2 IV | Interaction | ||
|---|---|---|---|---|---|
| (Intercept) | 4.34 (0.02)*** | 1.96 (0.04)*** | 3.19 (0.42)*** | 5.28 (0.87)*** | |
| gevocab | 0.53 (0.01)*** | 0.53 (0.01)*** | 0.01 (0.19) | ||
| age | -0.01 (0.00)** | -0.03 (0.01)*** | |||
| gevocab:age | 0.00 (0.00)** | ||||
| R2 | 0.00 | 0.29 | 0.29 | 0.29 | |
| Adj. R2 | 0.00 | 0.29 | 0.29 | 0.29 | |
| Num. obs. | 10320 | 10320 | 10320 | 10320 | |
| RMSE | 2.33 | 1.97 | 1.97 | 1.96 | |
| p < 0.001, p < 0.01, p < 0.05 |
Assess the significance of terms in the last ‘best’ model
summary(fit_read_lm_3)
Call:
lm(formula = geread ~ gevocab * age, data = data_achieve)
Residuals:
Min 1Q Median 3Q Max
-6.2069 -1.1250 -0.4362 0.6041 8.6476
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.282607 0.869769 6.074 1.3e-09 ***
gevocab 0.009154 0.189113 0.048 0.961394
age -0.030814 0.008066 -3.820 0.000134 ***
gevocab:age 0.004830 0.001759 2.746 0.006039 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 1.965 on 10316 degrees of freedom
Multiple R-squared: 0.2902, Adjusted R-squared: 0.29
F-statistic: 1406 on 3 and 10316 DF, p-value: < 2.2e-16
sjstats::r2(fit_read_lm_3)
R-Squared for Generalized Linear Mixed Model
R-squared: 0.290
adjusted R-squared: 0.290
anova(fit_read_lm_3)
Analysis of Variance Table
Response: geread
Df Sum Sq Mean Sq F value Pr(>F)
gevocab 1 16224 16223.9 4202.2783 < 2.2e-16 ***
age 1 34 33.7 8.7356 0.003128 **
gevocab:age 1 29 29.1 7.5419 0.006039 **
Residuals 10316 39827 3.9
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
4.3.2 Visualize the Interaction
effects::Effect(focal.predictors = c("gevocab", "age"), # chooses defaul values for
mod = fit_read_lm_3) # continuous vars
gevocab*age effect
age
gevocab 82 95 110 120 140
0 2.755830 2.355243 1.893028 1.584884 0.9685969
3 3.971571 3.759370 3.514523 3.351291 3.0248284
6 5.187313 5.163497 5.136018 5.117699 5.0810599
8 5.997807 6.099582 6.217015 6.295304 6.4518809
10 6.808301 7.035667 7.298012 7.472909 7.8227019
effects::Effect(focal.predictors = c("gevocab", "age"), # chooses defaul values for
mod = fit_read_lm_3) %>% # continuous vars
data.frame() %>%
mutate(age = factor(age)) %>% # must make a factor to seperate lines
ggplot(aes(x = gevocab,
y = fit,
color = age)) +
geom_point() +
geom_line()
Here is a better version of the plot.
Age is in months, so we want multiples of 12 for good visualization
summary(data_achieve$age)/12 # divide by 12 to change months to years
Min. 1st Qu. Median Mean 3rd Qu. Max.
6.833 8.667 8.917 8.961 9.250 11.250
A good set set of illustrative ages could be: 7, 9, and 11:
c(7, 9, 11) * 12 # times by 12 to change years to months
[1] 84 108 132
effects::Effect(focal.predictors = c("gevocab", "age"),
mod = fit_read_lm_3,
xlevels = list(age = c(84, 108, 132))) %>% # age is in months
data.frame() %>%
mutate(age_yr = factor(age/12)) %>% # it would be nice to plot age in years
ggplot(aes(x = gevocab,
y = fit,
color = age_yr,
linetype = age_yr)) +
geom_line(size = 1.25) +
theme_bw() +
labs(title = "Best Linear Model - Disaggregated Data (OLS)",
x = "Vocabulary Score",
y = "Reading Score",
linetype = "Age (yrs)",
color = "Age (yrs)") +
theme(legend.position = c(0.85, 0.2),
legend.key.width = unit(2, "cm"),
legend.background = element_rect(color = "black")) +
scale_linetype_manual(values = c("solid", "longdash", "dotted")) +
scale_x_continuous(breaks = seq(from = 0, to = 11, by = 2)) +
scale_y_continuous(breaks = seq(from = 0, to = 11, by = 1))
4.4 MLM - Step 1: Null Model, only fixed and random intercepts
A so called Empty Model only includes random intercepts. No independent variables are involved, other the grouping or clustering variable that designates how level 1 units are nested within level 2 units. For a cross-sectional study design this would be the grouping variables, where as for longitudinal or repeated measures designs this would be the subject identifier. This nested structure variable should be set to have class factor
.
4.4.1 Fit the Model
fit_read_0ml <- lme4::lmer(geread ~ 1 + (1|school),
data = data_achieve,
REML = FALSE) # fit via ML (not the default)
fit_read_0re <- lme4::lmer(geread ~ 1 + (1|school) ,
data = data_achieve,
REML = TRUE) # fit = REML (the default)
Compare the two models to OLS:
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_lm_0,
fit_read_0ml,
fit_read_0re),
custom.model.names = c("OLS",
"MLM-ML",
"MLM-REML"),
caption = "MLM: NULL Model,two estimation methods",
caption.above = TRUE,
single.row = TRUE)
| OLS | MLM-ML | MLM-REML | ||
|---|---|---|---|---|
| (Intercept) | 4.34 (0.02)*** | 4.31 (0.05)*** | 4.31 (0.05)*** | |
| R2 | 0.00 | |||
| Adj. R2 | 0.00 | |||
| Num. obs. | 10320 | 10320 | 10320 | |
| RMSE | 2.33 | |||
| AIC | 46270.34 | 46274.31 | ||
| BIC | 46292.06 | 46296.03 | ||
| Log Likelihood | -23132.17 | -23134.15 | ||
| Num. groups: school | 160 | 160 | ||
| Var: school (Intercept) | 0.39 | 0.39 | ||
| Var: Residual | 5.05 | 5.05 | ||
| p < 0.001, p < 0.01, p < 0.05 |
Notice that the estimate for the intercept is nearly the same in the linear regression and intercept only models, but the standard errors are quite different. When there is clustering in sample, the result of ignoring it is under estimation of the standard errors and over stating the significance of associations. This table was made with the screenreg()
function in the self named package. I tend to prefer this display over stargazer()
.
4.4.2 Estimate the ICC
First, ask for the variance compenents:
lme4::VarCorr(fit_read_0re) %>%
print(comp = c("Variance", "Std.Dev"),
digits = 4)
Groups Name Variance Std.Dev.
school (Intercept) 0.3915 0.6257
Residual 5.0450 2.2461
sjstats::re_var(fit_read_0re)
Within-group-variance: 5.045
Between-group-variance: 0.392 (school)
\[ \begin{align*} \text{schools} \rightarrow \; & \sigma^2_{u0} = 0.6257^2 = 0.392 \\ \text{students within schools} \rightarrow \; & \sigma^2_{e} = 2.2461^2 = 5.045 \\ \end{align*} \]
Intraclass Correlation (ICC) Formula \[ \overbrace{\rho}^{\text{ICC}} = \frac{\overbrace{\sigma^2_{u0}}^{\text{Random Intercept}\atop\text{Variance}}} {\underbrace{\sigma^2_{u0}+\sigma^2_{e}}_{\text{Total}\atop\text{Variance}}} \tag{Hox 2.9} \]
Then you can manually caluclate the ICC.
0.392 / (0.392 + 5.045)
[1] 0.07209858
Or you can use the icc()
function in the sjstats
package.
sjstats::icc(fit_read_0re)
Linear mixed model
Family : gaussian (identity)
Formula: geread ~ 1 + (1 | school)
ICC (school): 0.0720
Note: On page 45 (Finch, Bolin, and Kelley 2016), the authors substituted standard deviations into the formula, rather than variances. The mistake is listed on their webpage errata (http://www.mlminr.com/errata) and is repeated through the text.
4.5 MLM - Step 2: Add Lower-level explanatory variables, fixed, ML
Variance Component models (steps 2 and 3) - decompose the INTERCEPT variance into different variance compondents for each level. The regression intercepts are assumed to varry ACROSS the groups, while the slopes are assumed fixed (no random effects).
Fixed effects selection should come prior to random effects. You should use Maximum Likelihood (ML) estimation when fitting these models.
-
IF: only level 1 predictors and random intercepts are incorporated
- Then: MLM \(\approx\) ANCOVA .
4.5.1 Add pupil’s vocab score as a fixed effects predictor
fit_read_1ml <- lme4::lmer(geread ~ gevocab + (1|school),
data = data_achieve,
REML = FALSE) # to compare fixed var sig
fit_read_1re <- lme4::lmer(geread ~ gevocab + (1|school),
data = data_achieve,
REML = TRUE) # for R-sq calcs
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_0ml,
fit_read_1ml),
custom.model.names = c("Null",
"w Pred"),
caption = "MLM: Investigate a Fixed Pupil-level Predictor",
caption.above = TRUE,
doctype = FALSE,
digits = 4)
| Null | w Pred | ||
|---|---|---|---|
| (Intercept) | 4.3068*** | 2.0231*** | |
| (0.0548) | (0.0492) | ||
| gevocab | 0.5130*** | ||
| (0.0084) | |||
| AIC | 46270.3388 | 43132.4318 | |
| BIC | 46292.0643 | 43161.3991 | |
| Log Likelihood | -23132.1694 | -21562.2159 | |
| Num. obs. | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | |
| Var: school (Intercept) | 0.3885 | 0.0987 | |
| Var: Residual | 5.0450 | 3.7661 | |
| p < 0.001, p < 0.01, p < 0.05 |
<IP_ADDRESS> Assess Significance of Effects
Likelihood Ratio Test (LRT)
Since models 0 and 1 are nested models, only differing by the the inclusion or exclusion of the fixed effects predictor gevocab
, AND both models were fit via Maximum Likelihood, we can compare the model fit may be compared via the Likilihood-Ratio Test (LRT). The Likelihood Ratio value (L. Ratio) is found by subtracting the two model’s -2 * logLik
or deviance
values. Significance is judged by the Chi Squared distribution, using the difference in the number of parameters fit as the degrees of freedom.
anova(fit_read_0ml, fit_read_1ml)
Data: data_achieve
Models:
fit_read_0ml: geread ~ 1 + (1 | school)
fit_read_1ml: geread ~ gevocab + (1 | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_0ml 3 46270 46292 -23132 46264
fit_read_1ml 4 43132 43161 -21562 43124 3139.9 1 < 2.2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
What does the model look like?
effects::Effect(focal.predictors = c("gevocab"),
mod = fit_read_1ml) %>%
data.frame() %>%
ggplot(aes(x = gevocab,
y = fit)) +
geom_ribbon(aes(ymin = lower,
ymax = upper),
alpha = .3) +
geom_line() +
theme_bw()
<IP_ADDRESS> Proportion of Variance Explained
Extract the variance-covariance estimates:
BL = BAseline: The Null Model (fit via REML)
sjstats::re_var(fit_read_0re)
Within-group-variance: 5.045
Between-group-variance: 0.392 (school)
\[ \sigma^2_{u0-BL} = 0.392 \\ \sigma^2_{e-BL} = 5.045 \]
MC = Model to Compare: Model with Predictor (fit via REML)
sjstats::re_var(fit_read_1re)
Within-group-variance: 3.766
Between-group-variance: 0.100 (school)
\[ \sigma^2_{u0-MC} = 0.100 \\ \sigma^2_{e-MC} = 3.766 \]
Level 1 \(R^2\) - Snijders and Bosker
Found on page 47 (Finch, Bolin, and Kelley 2016), theproportion of variance in the outcome explained by predictor on level one is given by:
Snijders and Bosker Formula - Level 1 \[ R^2_1 = 1 - \frac{\sigma^2_{e-MC} + \sigma^2_{u0-MC}} {\sigma^2_{e-BL} + \sigma^2_{u0-BL}} \]
Note: This formula also apprears in the Finch errata. The subscripts in the denominator of the fraction should be for model 0, not model 1. The formula is given correctly here. They did substitute in the correct values.
Calculate the value by hand:
1 - (0.100 + 3.766)/(0.392 + 5.045)
[1] 0.2889461
Or use the sjstats
package to help out:
1 - sum(sjstats::re_var(fit_read_1re)) / sum(sjstats::re_var(fit_read_0re))
[1] 0.288838
This means nearly 30% of the variance in reading scores, above and beyond that accounted for by school membership (i.e. school makeup or school-to-school variation), is attributable to vocabulary scores.
Level 1 \(R^2\) - Raudenbush and Bryk
Hox, Moerbeek, and Van de Schoot (2017) presents this formula on page 58 of chapter 2
Raudenbush and Bryk Approximate Formula - Level 1 \[ approx\; R^2_1 = \frac{\sigma^2_{e-BL} - \sigma^2_{e-MC}} {\sigma^2_{e-BL} } \tag{Hox 4.8} \]
Calculate the value by hand:
(5.045 - 3.766) / 5.045
[1] 0.2535183
Although slightly different in value and meaning, this value also conveys that vcabulary scores are highly associated with reading scores.
Level 2 \(R^2\) - Snijders and Bosker Formula Extended
Snijders and Bosker Formula Extended - Level 2 \[ R^2_2 = 1 - \frac{\frac{\sigma^2_{e-MC}}{B} + \sigma^2_{u0-MC}} {\frac{\sigma^2_{e-BL}}{B} + \sigma^2_{u0-BL}} \]
\(B\) is the average size of the Level 2 units (schools). Technically, you should use the harmonic mean, but unless the clusters differ greatly in size, it doesn’t make a huge difference.
- Average sample cluster size
num_subjects / num_schools
[1] 64.5
- Calculate by hand:
1 - ((3.766 / 64.5) + 0.100)/
((5.045 / 64.5) + 0.391)
[1] 0.6624428
This means that over two-thrids in school mean reading levelsmay be explained by their student’s vocabulary scores.
Level 2 \(R^2\) - Raudenbush and Bryk
Raudenbush and Bryk Approximate Formula - Level 2 \[ R^2_1 = \frac{\sigma^2_{u0-BL} - \sigma^2_{u0-MC}} {\sigma^2_{u0-BL} } \tag{Hox 4.9} \]
(0.392 - 0.100)/(0.392)
[1] 0.744898
Remeber that these ‘variance accounted for’ estimations are not as straight forwards as we would like.
4.5.2 Investigate More Level 1 Predictors
Part of investigating lower level explanatory variables, is checking for interactions between these variables. The interaction between fixed effects is also considered to be a fixed effect, so we need to employ Maximum Likelihood estimation to compare nested models.
fit_read_2ml <- lmer(geread ~ gevocab + age + (1 | school), # add main effect of age
data = data_achieve,
REML = FALSE)
fit_read_3ml <- lmer(geread ~ gevocab*age + (1 | school), # add interaction between vocab and age
data = data_achieve,
REML = FALSE)
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_1ml,
fit_read_2ml,
fit_read_3ml),
custom.model.names = c("Only Vocab",
"Both Main Effects",
"Interaction"),
caption = "MLM: Investigate Other Fixed Pupil-level Predictors",
caption.above = TRUE,
doctype = FALSE,
digits = 4)
| Only Vocab | Both Main Effects | Interaction | ||
|---|---|---|---|---|
| (Intercept) | 2.0231*** | 3.0049*** | 5.1874*** | |
| (0.0492) | (0.4172) | (0.8666) | ||
| gevocab | 0.5130*** | 0.5121*** | -0.0279 | |
| (0.0084) | (0.0084) | (0.1881) | ||
| age | -0.0091* | -0.0294*** | ||
| (0.0038) | (0.0080) | |||
| gevocab:age | 0.0050** | |||
| (0.0017) | ||||
| AIC | 43132.4318 | 43128.8201 | 43122.5687 | |
| BIC | 43161.3991 | 43165.0293 | 43166.0198 | |
| Log Likelihood | -21562.2159 | -21559.4100 | -21555.2844 | |
| Num. obs. | 10320 | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | 160 | |
| Var: school (Intercept) | 0.0987 | 0.0973 | 0.0977 | |
| Var: Residual | 3.7661 | 3.7646 | 3.7614 | |
| p < 0.001, p < 0.01, p < 0.05 |
<IP_ADDRESS> Assess Significance of Effects
Likelihood Ratio Test (LRT)
anova(fit_read_1ml, fit_read_2ml, fit_read_3ml)
Data: data_achieve
Models:
fit_read_1ml: geread ~ gevocab + (1 | school)
fit_read_2ml: geread ~ gevocab + age + (1 | school)
fit_read_3ml: geread ~ gevocab * age + (1 | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_1ml 4 43132 43161 -21562 43124
fit_read_2ml 5 43129 43165 -21559 43119 5.6117 1 0.017841 *
fit_read_3ml 6 43123 43166 -21555 43111 8.2514 1 0.004072 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Not only is student’s age predictive of their reading level (I could have guessed that), but that age moderated the relationship between vocabulary and reading.
<IP_ADDRESS> Visulaize the Interation
Visulaizations are extremely helpful to interpred interactions.
summary(data_achieve$age)
Min. 1st Qu. Median Mean 3rd Qu. Max.
82.0 104.0 107.0 107.5 111.0 135.0
effects::Effect(focal.predictors = c("gevocab", "age"), # variables involved in the interaction
mod = fit_read_3ml,
xlevels = list(age = c(84, 108, 132))) %>% # age is in months
data.frame() %>%
mutate(age_yr = factor(age/12)) %>% # it would be nice to plot age in years
ggplot(aes(x = gevocab,
y = fit,
color = age_yr)) +
geom_line() +
theme_bw()
There is a positive association between vocabulary and reading, but it is strongest for older childred. Among younger children, reading scores are more stable across vocabulary differences.
4.6 MLM - Step 3: Higher-level explanatory variables, fixed, ML
School enrollment (senroll
) applies to each school as a whole. When a variable is measured at a higher level, all units in the same group have the same value. In this case, all student in the same school have the same value for senroll
.
fit_read_4ml <- lme4::lmer(geread ~ gevocab*age + senroll + (1 | school),
data = data_achieve,
REML = FALSE)
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_0ml,
fit_read_3ml,
fit_read_4ml),
custom.model.names = c("Null",
"Level 1 only",
"Level 2 Pred"),
caption = "MLM: Investigate a Fixed School-Level Predictor",
caption.above = TRUE,
single.row = TRUE)
| Null | Level 1 only | Level 2 Pred | ||
|---|---|---|---|---|
| (Intercept) | 4.31 (0.05)*** | 5.19 (0.87)*** | 5.24 (0.87)*** | |
| gevocab | -0.03 (0.19) | -0.03 (0.19) | ||
| age | -0.03 (0.01)*** | -0.03 (0.01)*** | ||
| gevocab:age | 0.01 (0.00)** | 0.01 (0.00)** | ||
| senroll | -0.00 (0.00) | |||
| AIC | 46270.34 | 43122.57 | 43124.31 | |
| BIC | 46292.06 | 43166.02 | 43175.01 | |
| Log Likelihood | -23132.17 | -21555.28 | -21555.16 | |
| Num. obs. | 10320 | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | 160 | |
| Var: school (Intercept) | 0.39 | 0.10 | 0.10 | |
| Var: Residual | 5.05 | 3.76 | 3.76 | |
| p < 0.001, p < 0.01, p < 0.05 |
4.6.1 Assess Significance of Effects
Likelihood Ratio Test (LRT)
anova(fit_read_0ml, fit_read_3ml, fit_read_4ml)
Data: data_achieve
Models:
fit_read_0ml: geread ~ 1 + (1 | school)
fit_read_3ml: geread ~ gevocab * age + (1 | school)
fit_read_4ml: geread ~ gevocab * age + senroll + (1 | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_0ml 3 46270 46292 -23132 46264
fit_read_3ml 6 43123 43166 -21555 43111 3153.7701 3 <2e-16
fit_read_4ml 7 43124 43175 -21555 43110 0.2548 1 0.6137
fit_read_0ml
fit_read_3ml ***
fit_read_4ml
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
School enrollment (or size) does not seem be related to reading scores.
4.7 MLM - Step 4: Explanatory variables predict Slopes, random, REML
Random Coefficient models - decompose the SLOPE variance BETWEEN groups.
The fixed effect of the predictor captures the overall association it has with the outcome (intercept), while the random effect of the predictor captures the group-to-group variation in the association (slope). Note: A variable can be fit as BOTH a fixed and random effect.
fit_read_3re <- lme4::lmer(geread ~ gevocab*age + (1 | school), # refit the previous 'best' model via REML
data = data_achieve,
REML = TRUE)
#fit_read_5re <- lmer(geread ~ gevocab + (gevocab | school),
# data = achieve,
# REML = TRUE) # failed to converge :(
fit_read_5re <- lme4::lmer(geread ~ gevocab*age + (gevocab | school),
data = data_achieve,
REML = TRUE,
control = lmerControl(optimizer = "optimx", # get it to converge
calc.derivs = FALSE,
optCtrl = list(method = "nlminb",
starttests = FALSE,
kkt = FALSE)))
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_3re,
fit_read_5re),
custom.model.names = c("Rand Int",
"Rand Int and Slopes"),
caption = "MLM: Investigate Random Effects",
caption.above = TRUE,
single.row = TRUE)
| Rand Int | Rand Int and Slopes | ||
|---|---|---|---|
| (Intercept) | 5.19 (0.87)*** | 5.61 (0.87)*** | |
| gevocab | -0.03 (0.19) | -0.14 (0.19) | |
| age | -0.03 (0.01)*** | -0.03 (0.01)*** | |
| gevocab:age | 0.01 (0.00)** | 0.01 (0.00)*** | |
| AIC | 43155.49 | 43011.65 | |
| BIC | 43198.95 | 43069.58 | |
| Log Likelihood | -21571.75 | -21497.82 | |
| Num. obs. | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | |
| Var: school (Intercept) | 0.10 | 0.28 | |
| Var: Residual | 3.76 | 3.66 | |
| Var: school gevocab | 0.02 | ||
| Cov: school (Intercept) gevocab | -0.06 | ||
| p < 0.001, p < 0.01, p < 0.05 |
<IP_ADDRESS> Assess Significance of Effect
Likelihood Ratio Test (LRT) for Random Effects
You can use the Chi-squared LRT test based on deviances even though we fit our modesl with REML, since the models only differ in terms of including/exclusing of a random effects; they have same fixed effects. Just make sure to include the refit = FALSE
option.
anova(fit_read_3re, fit_read_5re, refit = FALSE)
Data: data_achieve
Models:
fit_read_3re: geread ~ gevocab * age + (1 | school)
fit_read_5re: geread ~ gevocab * age + (gevocab | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_3re 6 43155 43199 -21572 43143
fit_read_5re 8 43012 43070 -21498 42996 147.84 2 < 2.2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
There is evidence the effect child vocabulary has on reading varies across schools.
<IP_ADDRESS> Visualize the Model
What does the model look like?
effects::Effect(focal.predictors = c("gevocab", "age"),
mod = fit_read_5re, # just different model
xlevels = list(age = c(84, 108, 132))) %>%
data.frame() %>%
dplyr::mutate(age_yr = factor(age/12)) %>%
ggplot(aes(x = gevocab,
y = fit,
color = age_yr)) +
geom_line() +
theme_bw()
We are seeming much the same trends, but perhaps more separation between the lines.
4.8 MLM - Step 5: Cross-Level interactions between explanatory variables - fixed, ML
Cross-level interacitons involve variables at different levels. Here we will investigate the school-level enrollment moderating vocabulary’s effect since we say that vocab’s effect differs across schools (step 4).
Remember that an interaction beween fixed effects is also fixed.
fit_read_5ml <- lme4::lmer(geread ~ gevocab*age + (gevocab | school),
data = data_achieve,
REML = FALSE,
control = lmerControl(optimizer = "optimx",
calc.derivs = FALSE,
optCtrl = list(method = "nlminb",
starttests = FALSE,
kkt = FALSE)))
fit_read_6ml <- lme4::lmer(geread ~ gevocab*age + senroll + (gevocab | school),
data = data_achieve,
REML = FALSE)
fit_read_7ml <- lme4::lmer(geread ~ gevocab*age + gevocab*senroll + (gevocab | school),
data = data_achieve,
REML = FALSE)
fit_read_8ml <- lme4::lmer(geread ~ gevocab*age*senroll + (gevocab | school),
data = data_achieve,
REML = FALSE)
If you get thelmer()
message: Some predictor variables are on very different scales: consider rescaling, you can trust your results, but you really should try re-scaling your variables.
We are getting this message since gevoab
is on mostly a single digit scale,0 to 11.2, and age (in months) ranges in the low thripe-digits, 82 through 135, while school enrollment is in the mid-hundreds, 112-916. When we compute the interactions we get much, much larger values. Having variables on such widely different ranges of values can cause estimation problems.
data_achieve %>%
dplyr::mutate(gevocab_x_age = gevocab*age,
gevocab_x_senroll = gevocab*senroll,
gevocab_x_age_x_senroll = gevocab*senroll*age) %>%
dplyr::select(gevocab, age, senroll, gevocab_x_age, gevocab_x_senroll, gevocab_x_age_x_senroll) %>%
summary()
gevocab age senroll gevocab_x_age
Min. : 0.000 Min. : 82.0 Min. :115.0 Min. : 0.0
1st Qu.: 2.900 1st Qu.:104.0 1st Qu.:438.0 1st Qu.: 310.3
Median : 3.800 Median :107.0 Median :519.0 Median : 408.0
Mean : 4.494 Mean :107.5 Mean :533.4 Mean : 482.5
3rd Qu.: 5.200 3rd Qu.:111.0 3rd Qu.:644.0 3rd Qu.: 560.0
Max. :11.200 Max. :135.0 Max. :916.0 Max. :1355.2
gevocab_x_senroll gevocab_x_age_x_senroll
Min. : 0 Min. : 0
1st Qu.: 1378 1st Qu.: 148054
Median : 1998 Median : 214379
Mean : 2401 Mean : 257821
3rd Qu.: 2970 3rd Qu.: 319752
Max. :10259 Max. :1149030
For now, let us look at the results.
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_3ml,
fit_read_6ml,
fit_read_7ml,
fit_read_8ml),
custom.model.names = c("Level 1 only",
"Both Levels",
"Cross-Level",
"3-way"),
caption = "MLM: Investigate a Fixed Cross-level Interaction",
caption.above = TRUE,
single.row = TRUE)
| Level 1 only | Both Levels | Cross-Level | 3-way | ||
|---|---|---|---|---|---|
| (Intercept) | 5.19 (0.87)*** | 5.60 (0.88)*** | 5.52 (0.89)*** | 5.50 (3.11) | |
| gevocab | -0.03 (0.19) | -0.14 (0.19) | -0.11 (0.20) | 0.53 (0.66) | |
| age | -0.03 (0.01)*** | -0.03 (0.01)*** | -0.03 (0.01)*** | -0.03 (0.03) | |
| gevocab:age | 0.01 (0.00)** | 0.01 (0.00)*** | 0.01 (0.00)*** | 0.00 (0.01) | |
| senroll | 0.00 (0.00) | 0.00 (0.00) | 0.00 (0.01) | ||
| gevocab:senroll | -0.00 (0.00) | -0.00 (0.00) | |||
| age:senroll | -0.00 (0.00) | ||||
| gevocab:age:senroll | 0.00 (0.00) | ||||
| AIC | 43122.57 | 42981.70 | 42983.44 | 42982.85 | |
| BIC | 43166.02 | 43046.87 | 43055.86 | 43069.75 | |
| Log Likelihood | -21555.28 | -21481.85 | -21481.72 | -21479.43 | |
| Num. obs. | 10320 | 10320 | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | 160 | 160 | |
| Var: school (Intercept) | 0.10 | 0.27 | 0.27 | 0.27 | |
| Var: Residual | 3.76 | 3.66 | 3.66 | 3.66 | |
| Var: school gevocab | 0.02 | 0.02 | 0.02 | ||
| Cov: school (Intercept) gevocab | -0.06 | -0.06 | -0.06 | ||
| p < 0.001, p < 0.01, p < 0.05 |
There is no evidence school enrollment moderates either of age or vocabulary’s effects.
<IP_ADDRESS> Assess Significance of Effects
Likelihood Ratio Test (LRT)
When you have a list of sequentially nested models, you can test them in order with one call to the anova()
funtion.
anova(fit_read_3ml, fit_read_6ml, fit_read_7ml, fit_read_8ml)
Data: data_achieve
Models:
fit_read_3ml: geread ~ gevocab * age + (1 | school)
fit_read_6ml: geread ~ gevocab * age + senroll + (gevocab | school)
fit_read_7ml: geread ~ gevocab * age + gevocab * senroll + (gevocab | school)
fit_read_8ml: geread ~ gevocab * age * senroll + (gevocab | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_3ml 6 43123 43166 -21555 43111
fit_read_6ml 9 42982 43047 -21482 42964 146.8710 3 <2e-16 ***
fit_read_7ml 10 42983 43056 -21482 42963 0.2534 1 0.6147
fit_read_8ml 12 42983 43070 -21479 42959 4.5932 2 0.1006
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
4.9 Centering Predictors: Change Center
Centering variables measured on the lowest level only involves subtacting the mean from every value. The spread or standard deviation is not changed.
Although there are functions to automatically center and standardize variables, it is beneficial to manually create these variables, as it is more transparent and facilitates un-centering them later.
4.9.1 Compute the Grand Means
# Knit to Website: output = "html"
# Knit to PDF: output = "latex2"
# View on Screen: output = ""text", or "markdown", "html"
data_achieve %>%
furniture::table1(gevocab, age, senroll,
output = "html",
digits = 4)
| Mean/Count (SD/%) | |
|---|---|
| n = 10320 | |
| gevocab | |
| 4.4938 (2.3679) | |
| age | |
| 107.5290 (5.0596) | |
| senroll | |
| 533.4148 (154.7968) |
<IP_ADDRESS> Subtract the Grand Mean
Subract the grand-mean from each observation’s vale to create grand-mean centered variables.
data_achieve_center <- data_achieve %>%
dplyr::mutate(gevocab_c = gevocab - 4.4938) %>%
dplyr::mutate(age_c = age - 107.5290) %>%
dplyr::mutate(senroll_c = senroll - 533.4148)
<IP_ADDRESS> Compare the centered and uncentered measures
View the first and last few observations:
data_achieve_center %>%
dplyr::select(id, school,
gevocab, gevocab_c,
age, age_c,
senroll, senroll_c) %>%
headTail()
id school gevocab gevocab_c age age_c senroll senroll_c
1 1 767 3.1 -1.39 104 -3.53 463 -70.41
2 2 767 2.8 -1.69 106 -1.53 463 -70.41
3 3 767 1.7 -2.79 112 4.47 463 -70.41
4 4 767 2.1 -2.39 109 1.47 463 -70.41
5 <NA> <NA> ... ... ... ... ... ...
6 7893 9085 4.7 0.21 108 0.47 603 69.59
7 7894 9085 3.1 -1.39 108 0.47 603 69.59
8 7895 9085 3.8 -0.69 114 6.47 603 69.59
9 7896 9085 3 -1.49 106 -1.53 603 69.59
Compare the summary statistcs:
# Knit to Website: output = "html"
# Knit to PDF: output = "latex2"
# View on Screen: output = ""text", or "markdown", "html"
data_achieve_center %>%
furniture::table1(gevocab, gevocab_c,
age, age_c,
senroll, senroll_c,
output = "html",
digits = 4)
| Mean/Count (SD/%) | |
|---|---|
| n = 10320 | |
| gevocab | |
| 4.4938 (2.3679) | |
| gevocab_c | |
| 0.0000 (2.3679) | |
| age | |
| 107.5290 (5.0596) | |
| age_c | |
| -0.0000 (5.0596) | |
| senroll | |
| 533.4148 (154.7968) | |
| senroll_c | |
| 0.0000 (154.7968) |
4.9.2 Use Centered Variables
NOTE: The models with CENTERED variables are able to be fit with the default optimizer settings and do not return the error: “unable to evaluate scaled gradientModel failed to converge: degenerate Hessian with 1 negative eigenvalues”
fit_read_9ml <- lme4::lmer(geread ~ gevocab + age + (gevocab | school),
data = data_achieve_center,
REML = FALSE,
control = lmerControl(optimizer = "optimx",
calc.derivs = FALSE,
optCtrl = list(method = "nlminb",
starttests = FALSE,
kkt = FALSE)))
fit_read_10ml <- lme4::lmer(geread ~ gevocab*age + (gevocab | school),
data = data_achieve_center,
REML = FALSE,
control = lmerControl(optimizer = "optimx",
calc.derivs = FALSE,
optCtrl = list(method = "nlminb",
starttests = FALSE,
kkt = FALSE)))
fit_read_9ml_c <- lme4::lmer(geread ~ gevocab_c + age_c + (gevocab_c | school),
data = data_achieve_center,
REML = FALSE)
fit_read_10ml_c <- lme4::lmer(geread ~ gevocab_c*age_c + (gevocab_c | school),
data = data_achieve_center,
REML = FALSE)
<IP_ADDRESS> Compare the Models
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_9ml,
fit_read_10ml,
fit_read_9ml_c,
fit_read_10ml_c),
custom.model.names = c("Main Effects",
"Interaction",
"Main Effects",
"Interaction"),
groups = list("Raw Scale" = 2:4,
"Mean Centered" = 5:7),
caption = "MLM: Investigate Centering Variables Involved in an Interaction",
caption.above = TRUE,
single.row = TRUE)
| Main Effects | Interaction | Main Effects | Interaction | ||
|---|---|---|---|---|---|
| (Intercept) | 2.98 (0.41)*** | 5.61 (0.87)*** | 4.34 (0.03)*** | 4.35 (0.03)*** | |
| Raw Scale | |||||
| gevocab | 0.52 (0.01)*** | -0.14 (0.19) | |||
| age | -0.01 (0.00)* | -0.03 (0.01)*** | |||
| gevocab:age | 0.01 (0.00)*** | ||||
| Mean Centered | |||||
| gevocab_c | 0.52 (0.01)*** | 0.52 (0.01)*** | |||
| age_c | -0.01 (0.00)* | -0.01 (0.00) | |||
| gevocab_c:age_c | 0.01 (0.00)*** | ||||
| AIC | 42989.44 | 42979.71 | 42989.44 | 42979.71 | |
| BIC | 43040.13 | 43037.65 | 43040.13 | 43037.65 | |
| Log Likelihood | -21487.72 | -21481.86 | -21487.72 | -21481.86 | |
| Num. obs. | 10320 | 10320 | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | 160 | 160 | |
| Var: school (Intercept) | 0.27 | 0.27 | 0.10 | 0.10 | |
| Var: school gevocab | 0.02 | 0.02 | |||
| Cov: school (Intercept) gevocab | -0.06 | -0.06 | |||
| Var: Residual | 3.66 | 3.66 | 3.66 | 3.66 | |
| Var: school gevocab_c | 0.02 | 0.02 | |||
| Cov: school (Intercept) gevocab_c | 0.02 | 0.02 | |||
| p < 0.001, p < 0.01, p < 0.05 |
Notice that the interactions yield the exact same parameter estimates and significances, but the main effects (including the interactions) are different. Model fit statistics include \(-2LL\) are exactly the same, too.
anova(fit_read_9ml, fit_read_10ml)
Data: data_achieve_center
Models:
fit_read_9ml: geread ~ gevocab + age + (gevocab | school)
fit_read_10ml: geread ~ gevocab * age + (gevocab | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_9ml 7 42989 43040 -21488 42975
fit_read_10ml 8 42980 43038 -21482 42964 11.726 1 0.0006162 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(fit_read_9ml_c, fit_read_10ml_c)
Data: data_achieve_center
Models:
fit_read_9ml_c: geread ~ gevocab_c + age_c + (gevocab_c | school)
fit_read_10ml_c: geread ~ gevocab_c * age_c + (gevocab_c | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_9ml_c 7 42989 43040 -21488 42975
fit_read_10ml_c 8 42980 43038 -21482 42964 11.726 1 0.0006162
fit_read_9ml_c
fit_read_10ml_c ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
<IP_ADDRESS> Visualize the Model
What does the model look like?
First plot the model fit to the centered variables with all defaut settings.
effects::Effect(focal.predictors = c("gevocab_c", "age_c"),
mod = fit_read_10ml_c) %>%
data.frame() %>%
dplyr::mutate(age_c = factor(age_c)) %>%
ggplot(aes(x = gevocab_c,
y = fit,
color = age_c)) +
geom_line() +
theme_bw()
Notice that the vocab and ages are centered at zero. This makes it hard to read the plot, especially if we are unsure what the means of the variables were.
Plot the model again, but this time UN-centering the variables by adding back the grand-mean we subtracted prior to fitting the model.
effects::Effect(focal.predictors = c("gevocab_c", "age_c"),
mod = fit_read_10ml_c,
xlevels = list(age_c = c(84, 108,<PHONE_NUMBER>)) %>% # add back the mean of age
data.frame() %>%
dplyr::mutate(age_yrs = factor((age_c + 107.5290)/12)) %>% # add back the mean of age
dplyr::mutate(gevocab = gevocab_c + 4.4938) %>% # add back the mean of vocab
ggplot(aes(x = gevocab,
y = fit,
color = age_yrs)) +
geom_line() +
theme_bw()
Now the plot is back on to the origial variables.
4.10 Rescaling Predictors: Change Units or Standardize
Where centering variables involved subtracting a set value, scalling a varaibles involves dividing by a set amount. When we both center to the mean and divide by the standard deviation, the new resulting varaible is said to be standardized (not to be confusing with normalizing, which is does not do).
To retain meaningful units, you can multiply or divide all the measured values of a variable by a set amount, like a multiple of 10. This retains the meaning behind the units while still bringing them into line with other variables in the model and can avoid some convergence issues.
4.10.1 Scale Varaibles
<IP_ADDRESS> Divide by a Meaningful Value
data_achieve_center %>%
dplyr::select(senroll_c, ses) %>%
summary()
senroll_c ses
Min. :-418.41 Min. : 0.00
1st Qu.: -95.41 1st Qu.: 66.30
Median : -14.41 Median : 81.70
Mean : 0.00 Mean : 72.85
3rd Qu.: 110.59 3rd Qu.: 87.80
Max. : 382.59 Max. :100.00
For this situation, lets both center at the mean and scale (by 100) the school enrollemnt variable. For SES, lets only divide by ten.
data_achieve_center_scale <- data_achieve_center %>%
dplyr::mutate(senroll_ch = senroll_c / 100) %>% # centered AND divided by one hundred
dplyr::mutate(ses_t = ses / 10) # JUST divide by ten
<IP_ADDRESS> Compare the scaled and unscaled measures
View the first and last few observations:
data_achieve_center_scale %>%
dplyr::select(id, school,
age_c, gevocab_c,
senroll, senroll_c, senroll_ch,
ses, ses_t) %>%
headTail()
id school age_c gevocab_c senroll senroll_c senroll_ch ses ses_t
1 1 767 -3.53 -1.39 463 -70.41 -0.7 80.4 8.04
2 2 767 -1.53 -1.69 463 -70.41 -0.7 80.4 8.04
3 3 767 4.47 -2.79 463 -70.41 -0.7 80.4 8.04
4 4 767 1.47 -2.39 463 -70.41 -0.7 80.4 8.04
5 <NA> <NA> ... ... ... ... ... ... ...
6 7893 9085 0.47 0.21 603 69.59 0.7 84.4 8.44
7 7894 9085 0.47 -1.39 603 69.59 0.7 84.4 8.44
8 7895 9085 6.47 -0.69 603 69.59 0.7 84.4 8.44
9 7896 9085 -1.53 -1.49 603 69.59 0.7 84.4 8.44
Compare the summary statistcs:
# Knit to Website: output = "html"
# Knit to PDF: output = "latex2"
# View on Screen: output = ""text", or "markdown", "html"
data_achieve_center_scale %>%
furniture::table1(senroll, senroll_c, senroll_ch,
ses, ses_t,
output = "html",
digits = 4)
| Mean/Count (SD/%) | |
|---|---|
| n = 10320 | |
| senroll | |
| 533.4148 (154.7968) | |
| senroll_c | |
| 0.0000 (154.7968) | |
| senroll_ch | |
| 0.0000 (1.5480) | |
| ses | |
| 72.8490 (21.9817) | |
| ses_t | |
| 7.2849 (2.1982) |
4.10.2 Use Scaled Variables
Using the new versions of our variables, investigate is SES has an effect, either in 2-way or 3-way interactions with age and vocabulary.
fit_read_10ml_s <- lme4::lmer(geread ~ gevocab_c*age_c + # no SES
(gevocab_c | school),
data = data_achieve_center_scale,
REML = FALSE)
fit_read_11ml_s <- lme4::lmer(geread ~ gevocab_c*age_c + gevocab_c*ses_t + # 2 2-way interactions
(gevocab_c | school),
data = data_achieve_center_scale,
REML = FALSE)
fit_read_12ml_s <- lme4::lmer(geread ~ gevocab_c*age_c*ses_t + # 3-way interaction
(gevocab_c | school),
data = data_achieve_center_scale,
REML = FALSE)
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_10ml_s,
fit_read_11ml_s,
fit_read_12ml_s),
custom.model.names = c("no SES",
"2-way",
"3-way"),
caption = "MLM: Investigate More Complex Fixed Interactions",
caption.above = TRUE,
single.row = TRUE)
| no SES | 2-way | 3-way | ||
|---|---|---|---|---|
| (Intercept) | 4.35 (0.03)*** | 3.94 (0.11)*** | 3.94 (0.11)*** | |
| gevocab_c | 0.52 (0.01)*** | 0.67 (0.05)*** | 0.67 (0.05)*** | |
| age_c | -0.01 (0.00) | -0.00 (0.00) | -0.01 (0.01) | |
| gevocab_c:age_c | 0.01 (0.00)*** | 0.01 (0.00)** | 0.00 (0.01) | |
| ses_t | 0.06 (0.01)*** | 0.06 (0.01)*** | ||
| gevocab_c:ses_t | -0.02 (0.01)** | -0.02 (0.01)** | ||
| age_c:ses_t | 0.00 (0.00) | |||
| gevocab_c:age_c:ses_t | 0.00 (0.00) | |||
| AIC | 42979.71 | 42928.81 | 42932.05 | |
| BIC | 43037.65 | 43001.23 | 43018.95 | |
| Log Likelihood | -21481.86 | -21454.41 | -21454.02 | |
| Num. obs. | 10320 | 10320 | 10320 | |
| Num. groups: school | 160 | 160 | 160 | |
| Var: school (Intercept) | 0.10 | 0.08 | 0.08 | |
| Var: school gevocab_c | 0.02 | 0.02 | 0.02 | |
| Cov: school (Intercept) gevocab_c | 0.02 | 0.03 | 0.03 | |
| Var: Residual | 3.66 | 3.66 | 3.66 | |
| p < 0.001, p < 0.01, p < 0.05 |
anova(fit_read_10ml_s, fit_read_11ml_s, fit_read_12ml_s)
Data: data_achieve_center_scale
Models:
fit_read_10ml_s: geread ~ gevocab_c * age_c + (gevocab_c | school)
fit_read_11ml_s: geread ~ gevocab_c * age_c + gevocab_c * ses_t + (gevocab_c |
fit_read_11ml_s: school)
fit_read_12ml_s: geread ~ gevocab_c * age_c * ses_t + (gevocab_c | school)
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
fit_read_10ml_s 8 42980 43038 -21482 42964
fit_read_11ml_s 10 42929 43001 -21454 42909 54.8974 2 1.2e-12
fit_read_12ml_s 12 42932 43019 -21454 42908 0.7674 2 0.6813
fit_read_10ml_s
fit_read_11ml_s ***
fit_read_12ml_s
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
There is evidence that SES moderates the main effect of vocabualry, after accounting for the interaction between age and vocabulary.
4.11 Final Model
Always refit the final model via REML.
fit_read_11re_s <- lme4::lmer(geread ~ gevocab_c*age_c + gevocab_c*ses_t + # 2 2-way interactions
(gevocab_c | school),
data = data_achieve_center_scale,
REML = TRUE)
4.11.1 Table
# Knit to Website: texreg::htmlreg()
# Knit to PDF: texreg::texreg()
# View on Screen: texreg::screenreg()
texreg::htmlreg(list(fit_read_11re_s),
caption = "MLM: Final Model",
caption.above = TRUE,
single.row = TRUE)
| Model 1 | ||
|---|---|---|
| (Intercept) | 3.94 (0.11)*** | |
| gevocab_c | 0.67 (0.05)*** | |
| age_c | -0.00 (0.00) | |
| ses_t | 0.06 (0.01)*** | |
| gevocab_c:age_c | 0.01 (0.00)** | |
| gevocab_c:ses_t | -0.02 (0.01)** | |
| AIC | 42976.51 | |
| BIC | 43048.93 | |
| Log Likelihood | -21478.26 | |
| Num. obs. | 10320 | |
| Num. groups: school | 160 | |
| Var: school (Intercept) | 0.08 | |
| Var: school gevocab_c | 0.02 | |
| Cov: school (Intercept) gevocab_c | 0.03 | |
| Var: Residual | 3.66 | |
| p < 0.001, p < 0.01, p < 0.05 |
<IP_ADDRESS> Visualize the Model
Recall the scales that the revised variables are now on:
data_achieve_center_scale %>%
dplyr::select(gevocab_c, age_c, ses_t) %>%
summary()
gevocab_c age_c ses_t
Min. :-4.493800 Min. :-25.529000 Min. : 0.000
1st Qu.:-1.593800 1st Qu.: -3.529000 1st Qu.: 6.630
Median :-0.693800 Median : -0.529000 Median : 8.170
Mean : 0.000044 Mean : -0.000027 Mean : 7.285
3rd Qu.: 0.706200 3rd Qu.: 3.471000 3rd Qu.: 8.780
Max. : 6.706200 Max. : 27.471000 Max. :10.000
effects::Effect(focal.predictors = c("gevocab_c", "age_c", "ses_t"),
mod = fit_read_11re_s,
xlevels = list(age_c = c(84, 108,<PHONE_NUMBER>,
ses_t = c(0, 5, 10))) %>%
data.frame() %>%
dplyr::mutate(age_yrs = factor((age_c + 107.5290)/12)) %>%
dplyr::mutate(gevocab = gevocab_c + 4.4938) %>%
dplyr::mutate(ses = factor(ses_t * 10)) %>%
ggplot(aes(x = gevocab,
y = fit,
color = age_yrs)) +
geom_line() +
theme_bw() +
facet_grid(.~ ses, labeller = "label_both") +
labs(x = "Vocabulary Score",
y = "Reading Score\nEstimated Marginal Mean",
color = "Student Age")
There is evidence that higher vocabulary scores correlate with higher reading scores. This relationship os strongest in low SES schools and among older students. This relationship is especially weaker in younger students attending high SES schools.
See: Nakagawa and Schielzeth (2013) for more regarding model \(R^2\)
From the sjstats::r2()
documentation, for mixed models:
- marginal r-squared considers only the variance of the fixed effects
- conditional r-squared takes both the fixed and random effects into account
sjstats::r2(fit_read_11re_s)
R-Squared for Generalized Linear Mixed Model
Family : gaussian (identity)
Formula: geread ~ gevocab_c * age_c + gevocab_c * ses_t + (gevocab_c | school)
Marginal R2: 0.289
Conditional R2: 0.322
Helpful links:
http://maths-people.anu.edu.au/~johnm/r-book/xtras/mlm-ohp.pdf
http://ase.tufts.edu/gsc/gradresources/guidetomixedmodelsinr/mixed%20model%20guide.html
http://web.stanford.edu/class/psych252/section_2015/Section_week9.html
https://www.r-bloggers.com/visualizing-generalized-linear-mixed-effects-models-part-2-rstats-lme4/


{% extends "base.html" %}
{% block css %}
{% endblock %}
{% block js %}
{% endblock %}
{% block content %}
To invite users to the user please provide us with their e-mail address. We shall e-mail them with a link to a account setup page for them to input their information.
| Username | Full name | Disipline | Authority |
|---|---|---|---|
| {{user["username"]}} | {{user["title"]}} {{user["firstname"]}} {{user["lastname"]}} | Computer Science | {{authorities[user["permission"]]}} |


Welcome to the FXPAL Suitable page
If you want to use or learn about our Suitable Beam or double robotics telepresence robots, see Jim Vaughan or connect to the mediation server!


It all starts from the director. Director is a base object needed for every game and connects all LimeJS logic to a single place on the webpage. If you come from flash world you can think of it as a stage, Cocos2d users see familiarities with Cocos2d-s own Director. All other can think of it just as a front controller.
There is only one director instance for each game. It handles games global viewport and controls which scenes are visible. In the beginning of your came logic you have to create an instance of director. The parameters for the constructor method are container DOM element, stage width in pixels and height in pixels.
#!JavaScript
var director = new dfkit.Director(document.body,320,460);
Scene is a independent portion of visible elements that cover all the viewport. This means that only one scene can be active at a given time. For example, in common game logic you would have menu scene, play scene and game-over scene. To make a scene visible you call ’director.replaceScene(scene)’ or ’director.pushScene(scene)’. The difference is that pushScene does not remove the previous scene but keeps it in a hidden stack so it can be made visible again with ’director.popScene()’ call.
#!JavaScript
var scene = new lime.Scene();
director.replaceScene(scene);
Using plain ’replaceScene()’ just makes a quick switch between the scenes that may not be visually appealing. To make it better you can set optional transition and duration property of your ’replaceScene()’ call. The transition defines the animation that happens when current scene is dismissed and new scene is activated. Currently various Slide and Move transitions are supported as well as Dissolve for fade-in effect.
#!JavaScript
director.replaceScene(menuscene,lime.transition.SlideInRight);
director.replaceScene(gamescene,lime.transition.Dissolve,2);
Everything in Lime is drawn with repaint-dirty pattern. That means that every time you change something your method calls aren't strictly related to the equivalent DOM or Canvas2dContext calls. Instead property you set is marked as dirty and will be redrawn in the next frame. This allows us to update only once, update only what is necessary and keep all updates stateless. Last criteria allows us to switch between the renderer methods any time. As there isn't any on-enter-frame event in Javascript we've made a lime.sheduleManager static object that simulates it. These are the methods it provides:
You should never use JavaScript built in methods ’setTimeout()’ and ’setInterval()’ directly in your game code. lime.schduleManager provides you with the same functionality with extra features. Your callback is called with a parameter that is the delay from the last execution of the same callback in milliseconds. This allows you to make smooth animations even if the CPU performance changes drastically.
#!JavaScript
var velocity = 2;
lime.scheduleManager.schedule(function(dt){
var position = this.getPosition();
position.x += velocity * dt; // if dt is bigger we just move more
this.setPosition(position);
},ball);
Using scheduleManager instead of timer functions also gives you benefit of pausing support. When you wish to pause your gave you simply have to call the ’setPaused(true)’ on your Director object. This pauses all the scheduled functions and animations. Once you resume by calling ’setPaused(false)’ all your code is resumed as if nothing ever happened. While your game is in paused state instance of lime.PauseScene is placed as a active scene of the Director. If you wish to have some custom appearance on this state you can override this class functionality.
#!JavaScript
mygame.director.setPaused(true);
Now we are ready to add something on the screen. To better manage your display object we have introduced lime.Layer objects. You can think about them in a same way as Photoshop layers. Layers are there to hold stuff in. They act as any other display objects with an exception that they don't have any body or size themselves. Their only contents is their children objects. So you create them, add to the tree, position if necessary and add child objects into to them. Just to be clear, using layers is not required - your can add any display objects to the scene. Layers just make your life easier.
#!JavaScript
var layer = new lime.Layer().setPosition(100,100);
scene.appendChild(layer);
for(var i=0;i<5;i++){
var box = customMakeBoxFunc().setPosition(i*50,0);
layer.appendChild(box);
}


#include <matcher.hpp>
|
| | matcher (const std::string matchMethod) |
| | matcher constructor More...
|
| |
| void | matchDescriptors (const cv::Mat &descriptors_1, const cv::Mat &descriptors_2, std::vector< cv::DMatch > &thismatch) |
| | this function matches descriptors More...
|
| |
| void | matchFilter (const std::vector< cv::DMatch > &rawMatches, const double threshold, std::vector< cv::DMatch > &goodMatches) |
| | this function filters matching results by matching distance More...
|
| |
| void | epipolarRejector (const std::vector< cv::DMatch > &goodMatches, camera &camLeft, camera &camRight, std::vector< cv::DMatch > &horizontalMatches) |
| | this function filters matching results by epipolar constriants More...
|
| |
| void | biDirecRejector (const std::vector< cv::DMatch > &rawMatches, const std::vector< cv::DMatch > &rawMatches2, std::vector< cv::DMatch > &filteredMatches) |
| | this function filters matching results by bi-directional check More...
|
| |
| void | updateMatchPoints (camera &camLeft, camera &camRight, const std::vector< cv::DMatch > &matches) |
| |
| void | updateMatchPoints2 (camera &camLast, camera &camCurrent, const std::vector< cv::DMatch > &matches) |
| |
| matcher::matcher |
( |
const std::string |
matchMethod | ) |
|
matcher constructor
- Parameters
-
| [in] | method | matching method :BruteForce (it uses L2 ), BruteForce-L1 , BruteForce-Hamming , BruteForce-Hamming(2) , FlannBased |
| void matcher::biDirecRejector |
( |
const std::vector< cv::DMatch > & |
rawMatches, |
|
|
const std::vector< cv::DMatch > & |
rawMatches2, |
|
|
std::vector< cv::DMatch > & |
filteredMatches |
|
) |
| |
this function filters matching results by bi-directional check
- Parameters
-
| [in] | rawMatches1 | matches to be filtered |
| [in] | rawMatches2 | inverse matching of rawMatches1 |
| [out] | filteredMatches | filtered matches |
| void matcher::epipolarRejector |
( |
const std::vector< cv::DMatch > & |
goodMatches, |
|
|
camera & |
camLeft, |
|
|
camera & |
camRight, |
|
|
std::vector< cv::DMatch > & |
horizontalMatches |
|
) |
| |
this function filters matching results by epipolar constriants
- Parameters
-
| [in] | goodMatches | matches to be filtered |
| [in] | camLeft | left camera |
| [in] | camRight | right camera |
| [out] | horizontalMatches | filtered matches |
| void matcher::matchDescriptors |
( |
const cv::Mat & |
descriptors_1, |
|
|
const cv::Mat & |
descriptors_2, |
|
|
std::vector< cv::DMatch > & |
thismatch |
|
) |
| |
this function matches descriptors
- Parameters
-
| [in] | descriptors_1 | descriptors to be matched |
| [in] | descriptors_2 | same to descriptors_1 |
| [out] | thismatch | matching indexes |
| void matcher::matchFilter |
( |
const std::vector< cv::DMatch > & |
rawMatches, |
|
|
const double |
threshold, |
|
|
std::vector< cv::DMatch > & |
goodMatches |
|
) |
| |
this function filters matching results by matching distance
- Parameters
-
| [in] | rawMatches | raw matches to be filtered |
| [in] | threshold | threshold ranges from 0 to 1. higher threshold tolorant larger matching distance. fewer matches of lower matching distance will be returned with lower threshold. |
| [out] | goodMatches | filtered matches |
this is match filter working on the matching distance. The largest and smallest distance will first be find out. Than the threshold passed in will generate a distance which is (smallest distance)+threshold*(largest distance - smallest distance). The matches larger than this distance will be filtered.
| void matcher::updateMatchPoints |
( |
camera & |
camLeft, |
|
|
camera & |
camRight, |
|
|
const std::vector< cv::DMatch > & |
matches |
|
) |
| |
| void matcher::updateMatchPoints2 |
( |
camera & |
camLast, |
|
|
camera & |
camCurrent, |
|
|
const std::vector< cv::DMatch > & |
matches |
|
) |
| |
| cv::Ptr<cv::DescriptorMatcher> matcher::thismatcher |
The documentation for this class was generated from the following files:
- /home/zhangtianyi/visual-odometry-custom/include/matcher.hpp
- /home/zhangtianyi/visual-odometry-custom/src/matcher.cpp


JavaScript is disabled on your browser.
Package
Class
Tree
Deprecated
Index
Help
Prev
Next
Frames
No Frames
All Classes
B
C
G
H
B
BCrypt
- Class in
<Unnamed>
BCrypt implements OpenBSD-style Blowfish password hashing using the scheme described in "A Future-Adaptable Password Scheme" by Niels Provos and David Mazieres.
BCrypt()
- Constructor for class
BCrypt
C
checkpw(String, String)
- Static method in class
BCrypt
Check that a plaintext password matches a previously hashed one
G
gensalt(int, SecureRandom)
- Static method in class
BCrypt
Generate a salt for use with the BCrypt.hashpw() method
gensalt(int)
- Static method in class
BCrypt
Generate a salt for use with the BCrypt.hashpw() method
gensalt()
- Static method in class
BCrypt
Generate a salt for use with the BCrypt.hashpw() method, selecting a reasonable default for the number of hashing rounds to apply
H
hashpw(String, String)
- Static method in class
BCrypt
Hash a password using the OpenBSD bcrypt scheme
B
C
G
H
Package
Class
Tree
Deprecated
Index
Help
Prev
Next
Frames
No Frames
All Classes


You might be thinking what am i doing..But seriously as soon as this holidays word arises, first there is so much happiness and unlimited dreamy plans!!!!we are going to do this and that but after almost three to four after completing our sleep we all have the same conditions that are shown above..
We again start to make some plans but the plans will not be going to bother a heap of these holidays..


Fresh Fruits
It has long been known that a diet that indicates at least a few servings of fresh fruit every day will help keep you healthy, fit and trim.
Title goes here
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O


Name must be at least 3 characters.
{{ errors.name }}
Image URI is required.
CloudFormation Template is required.
CloudFormation Template is not valid JSON.


Before Change
def train_ner(nlp, train_data, output_dir):
// Add new words to vocab
for raw_text, _ in train_data:
doc = nlp.make_doc(raw_text)
for word in doc:
_ = nlp.vocab[word.orth]
random.seed(0)
// You may need to change the learning rate. It"s generally difficult to
After Change
def train_ner(nlp, train_data, output_dir):
random.seed(0)
optimizer = nlp.begin_training(lambda: [])
nlp.meta["name"] = "en_ent_animal"
for itn in range(50):
losses = {}
for batch in minibatch(get_gold_parses(nlp.make_doc, train_data), size=3):


The world has changed to a mobile-first era but even today, none of the applications could emerge as effective as the web-based apps. Surfacing on top of this is the prevalence of progressive web apps that perform functions identical to mobile apps. So, it’s pretty clear that web apps are going to stay and for long. What makes these web applications worth investing is the use of high-end scalable technologies for the development or in simpler words, using top-notch quality technology stack.
No wonder, companies spend considerable time choosing the right technology stack for the development of web applications. It is this technology stack that determines the overall functionality of the applications, its interface, and potential features.
Additionally, choosing the most appropriate technology stack can leverage your application’s market reach and loop towards success. Likewise, using a poor technology stack might doom the entire project to failure. So, you see how important it is to have an in-depth review of the web development stack you are about to use for your project.
Though I might have till now convinced you of the importance of a web development stack and to adhere to the market standards while making a choice, you might still be boggling around what exactly is this technology stack?
Web Development Stack
When it comes to developing a web application, it’s not just about integrating an idea and giving it a visual appearance. It is far more than a non-technical individual could ever imagine. Web Development has two faces, one being the front-end development and the other being the back end. Or in simple words, the client-side and the server-side. The client-side is viewed by the user and is the front end whereas the server-side has a database application, an application that connects the client request to the database and the server itself.So, when an application needs to be developed, developers need to have considerable knowledge on both the ends along with the technologies to be used when deploying each.Client-side
HTML & CSS: HTML stands for HyperText Markup Language. It is used to design the front end portion of web pages using markup language. HTML is the combination of Hypertext and Markup language. Hypertext defines the link between the web pages. The markup language is used to define the text documentation within tag which defines the structure of web pages.
Cascading Style Sheets, fondly referred to as CSS, is a simply designed language intended to simplify the process of making web pages presentable. CSS allows you to apply styles to web pages. More importantly, CSS enables you to do this independent of the HTML that makes up each web page.
Server-side
For Server-Side: The commonly used server-side technologies consist of
Programming languages:
Ruby: Ruby is a dynamic, reflective, object-oriented, general-purpose programming language. Ruby is a pure Object-Oriented language developed by Yukihiro Matsumoto. Everything in Ruby is an object except the blocks but there are replacements too for it i.e procs and lambda.
Python: Python is a programming language that lets you work quickly and integrate systems more efficiently. There so many python frameworks like Django, Flask. Pylons etc.
C++: It is a general-purpose programming language and widely used nowadays for competitive programming. It is also used as a backend language.
PHP: PHP is a server-side scripting language designed specifically for web development. Since, PHP code executed on server side so it is called server side scripting language. laravel framework is the best in my opinion for PHP.
Java: Java is one of the most popular and widely used programming language and platform. It is highly scalable. Java components are easily available.
Scala: Scala is a general-purpose, high-level, multi-paradigm programming language. It is a pure object-oriented programming language which also provides support to the functional programming approach.
Database
Database:
Oracle: Oracle database is the collection of data that is treated as a unit. The purpose of this database is to store and retrieve information related to the query. It is a database server and used to manages information.
SQL: Structured Query Language is a standard Database language which is used to create, maintain and retrieve the relational database.
PostgreSQL: It is a powerful, open source object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.
MongoDB: MongoDB, the most popular NoSQL database, is an open source document-oriented database. The term ‘NoSQL’ means ‘non-relational’. It means that MongoDB isn’t based on the table-like relational database structure but provides an altogether different mechanism for storage and retrieval of data.
Server
Nginx: It's an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server.
Apache: It provides a high-level of abstraction for processing over the MapReduce. It provides a high-level scripting language, known as Pig Latin which is used to develop the data analysis codes. First, to process the data which is stored in the HDFS, the programmers will write the scripts using the Pig Latin Language.
Tips to choose the stack
Tips to choose a web tech stack So, now you know what web development is, why do you need it and what are the available web development stack. What’s next? Knowing is not enough, you need to have a clear image on how to choose the right web development stack for your web application.
Define Your Project Requirements: The project size and corresponding complexity are some of the most important aspects while choosing a tech stack. For smaller projects, you can go with Node.js Or python. Mid-sized projects have greater requirements and so you need to expand your stack, picking up technologies that map project needs. And similarly, for larger projects, it is necessary that you analyze each aspect and then deploy the right technology.
Development Time: In case you want the project to be developed in the minimal possible time, choosing ready-made solutions or frameworks that enable easy integration would cut down the fleet to market. A combination of technologies that form the MEAN stack is one of the most ideal stacks as it reduces the overall development time by third party integrations and this speeds up the entire process.
Scalability: For projects that necessitate upscaling, it becomes imperative to add technologies that have a future scope. Whether it is scaling upward or sideways, the choice of technology determines the potential of scalability.
 Choosing a stack that your developers aren’t experienced in, would doom the need to hire third-party developers. This might cost high in your pocket. Hence, before you make a decision on the web development stack, sit with your team, know what they consider appropriate and then end up on a sound decision.
Define Your Project Requirements: The project size and corresponding complexity are some of the most important aspects while choosing a tech stack. For smaller projects, you can go with Node.js Or python. Mid-sized projects have greater requirements and so you need to expand your stack, picking up technologies that map project needs. And similarly, for larger projects, it is necessary that you analyze each aspect and then deploy the right technology.
Development Time: In case you want the project to be developed in the minimal possible time, choosing ready-made solutions or frameworks that enable easy integration would cut down the fleet to market. A combination of technologies that form the MEAN stack is one of the most ideal stacks as it reduces the overall development time by third party integrations and this speeds up the entire process.
Scalability: For projects that necessitate upscaling, it becomes imperative to add technologies that have a future scope. Whether it is scaling upward or sideways, the choice of technology determines the potential of scalability.
 Choosing a stack that your developers aren’t experienced in, would doom the need to hire third-party developers. This might cost high in your pocket. Hence, before you make a decision on the web development stack, sit with your team, know what they consider appropriate and then end up on a sound decision.


Set the properties for the new root node and then click 'Submit'
WARNING: This will completely erase the current tree!
Category:1. Set the properties for the new node
2. Click on the branch of the tree where you want the node to be added.
Category:Click the node you want to remove.


#Rojal M.
"We build our computer the way we build our cities: over time, without a plan, on top of ruins."  Now is time to create one :)
Read


Docker is a container management service in which its purpose it to allow for developers to easily develop applications, ship them into containers which can be deployed anywhere. For this tutorial, we will learn how to build a web server on our local computer using Docker. Assuming that Docker has already been installed, we will use the Apache Web Server on Ubuntu.
After opening Docker, run docker pull ubuntu. This pulls the latest Ubuntu image from Dockerhub
By using docker images, you can check the existing Docker images on your computer
To run the Ubuntu image to start a Docker container, run docker run -it ubuntu:latest /bin/bash
After running the image, it is a good idea to make sure that all the packages pre-installed on the Ubuntu image are up to date. Run apt-get update as shown below.
After it has been updated, we are now ready to install apache2 using apt-get install apache2.
Then, the vim text editor can be installed using apt-get install vim.
After all the installations are complete, the Ubuntu container can be exited by using the command exit.
First, the container is checked by running docker ps -a.
A new Docker image can be created by running docker commit [container ID] [name of new Docker image] as shown below. In this specific instance, 4d13b78bd597 is the container ID and the name of the new Docker image is ubuntu-my_apache2.
Once a Docker container is stopped, data is not stored. Therefore, in order to have persistent data storage, Docker provides three different storage options, bind mounts, in-memory storage (tmpfs), and volumes. In this tutorial, we will use Docker volumes to store data.The advantage of using Docker volumes is that volumes are easier to back up and migrate. They are safer to share among containers.The following command should be used docker run -it -p <IP_ADDRESS>:80:80 -v [Host directory]:/var/www/html [Docker image name] /bin/bash.
A simple index.html can be created using the vi Editor. In order to access the editor, you should check the working directory in the following pathway.
Run vi index.html.
You should observe the following to enter the vi Editor. In order to make changes in the editor, type i in order to see the word Insert at the bottom of the editor.
Before
After
HTML code can now be entered. After you are done editting the index.html file, press ESC and then type :wq in order to quit the vi editor.
To start the Apache Server on Ubuntu,run service apache2 start.
Using a browser on your host computer, you can access the localhost address by typing in <IP_ADDRESS> and you should see the product of the code added in index.html!


--- title: Israel shot 189 date: 2004-07-08T00:00:00.000Z filepathOriginal: photos/IMG0096.jpg filepathThumbnail: photos/IMG0096.thumbnail.jpg filepathPreview: photos/IMG0096.preview.jpg ---
All done... looking pleased with my work, at the tree plantation


Public API for tf.queue namespace.
class FIFOQueue
: A queue implementation that dequeues elements in first-in first-out order.
class PaddingFIFOQueue
: A FIFOQueue that supports batching variable-sized tensors by padding.
class PriorityQueue
: A queue implementation that dequeues elements in prioritized order.
class QueueBase
: Base class for queue implementations.
class RandomShuffleQueue
: A queue implementation that dequeues elements in a random order.


Candidate Presentation for Systems and Discovery Services Librarian
Library Website in 2018
New Georgetown University Qatar Website in 2019
Example - Requirements Document
Project Stages
Directions
Building Access & Parking
The Georgetown University in Qatar Library...
The library welcomes all visitors...


Survey Questions
About You
Name (Required)
Link to Photo Image (Required)
Instructions:
Answer the following questions truthfully:
1 is 'Strongly Disagree' and 5 means 'Strongly Agree'
Question 1
You are creative and artistic.
Select an option
1
2
3
4
5
Question 2
You value beauty over brains.
Select an option
1
2
3
4
5
Question 3
You interact well with others in public settings.
Select an option
1
2
3
4
5
Question 4
You work hard toward professional goals.
Select an option
1
2
3
4
5
Question 5
You are outgoing and have a strong personality.
Select an option
1
2
3
4
5
Question 6
You have trouble making touch decisions under pressure.
Select an option
1
2
3
4
5
Question 7
You value family over religion.
Select an option
1
2
3
4
5
Question 8
You often have long term relationships.
Select an option
1
2
3
4
5
Question 9
You respect peoples opinions but have strong political views.
Select an option
1
2
3
4
5
Question 10
You are comfortable managing high paced leadership environments.
Select an option
1
2
3
4
5
Submit
API Friends List
|
GitHub Repo
×
Best Match!


States help run U.S. National Parks in federal government shutdown
(Reuters) - U.S. National Parks will be left with just a skeleton staff during the federal government shutdown, and several states are using their own funds to make sure public restrooms get cleaned and visitor centers stay open.
The shutdown of all but essential federal services due to a Capitol Hill fight over U.S. President Donald Trump’s funding demands for a Mexico border wall comes at the height of the Christmas travel season. The National Park Service said this week that parks will remain “as accessible as possible.” During a three-day government shutdown in January, the gates to about two-thirds of national parks and monuments remained open. “Services that require staffing and maintenance such as campgrounds and full-service restrooms will not be operating,” Jeremy Barnum, the National Parks Service chief spokesman, said in a statement.
The Republican governors of Utah and Arizona have promised to step in, in part to help protect local businesses in and around some of the country’s most spectacular natural landscapes that depend on tourist spending. “Regardless of what happens in Washington, the Grand Canyon will not close on our watch,” Arizona Governor Doug Ducey said in a statement on Friday. The Arizona Office of Tourism will help ensure restrooms are cleaned, trash is collected and shuttle buses operate, Ducey said.
All five of Utah’s national parks will remain open, and the three most popular will have maintenance costs underwritten by the state during the shutdown, according to Vicki Varela, the Utah Office of Tourism’s managing director. Zion National Park drew 107,000 visitors between Dec. 22 and Dec. 27 a year ago, Varela said. “This time of year is the most remarkable time of year to experience it because the snow against that red rock is just breathtaking,” she said. Utah Governor Gary Herbert authorized the temporary funding for custodial and visitor center services, which will cost an estimated $18,000 to $19,000 for Zion. “It’s really modest on the part of the state to protect the quality of the experience for visitors,” Varela said.
New York state has provided funding to keep the Statue of Liberty and Ellis Island open during the shutdown, according to the park’s website. New York Governor Andrew Cuomo, a Democrat, slammed Trump over the federal shutdown on Twitter on Saturday. Officials from the Great Smoky Mountains Association said the non-profit group would provide funding to maintain visitor center staffing, restroom cleaning and trash hauling at the Great Smoky Mountains National Park on the Tennessee-North Carolina border. The National Park Service said it would not be updating its social media accounts during the shutdown, and that while some park areas remain accessible, access could change without notice.
Some conservationists said it would be better to close parks entirely, as happened under President Barack Obama’s administration during a 2013 shutdown, rather than keep them open with skeleton staff. During the January shutdown, a pregnant elk was killed in Zion and tourists in Yellowstone National Park drove snowmobiles dangerously close to the Old Faithful geyser, said Theresa Pierno, president of the National Parks Conservation Association. “It’s unrealistic and dangerous to think that parks can remain open with only a skeleton crew and continue with business as usual,” Pierno said in a statement.


So, I’m still at the airport. American Airlines lied to the passengers and kept pushing the flight time back until they decided we weren’t gonna go. So, I’m just chilling in charlotte. Shoulda left at 8 pm, now I’m not leaving till 9am. Gotta love travel when when it goes double digits hour wise.
The photo is a picture of a turtle I took with my second daughter on a nature ride. I want to be home. So much time is spent removing parents from children in this modern setup. I think a lot has to do with the state foisting itself in a parental position to act like a shitty abusive parent to the youth. They want us dependent. A strong family unit is anti-thetical to that. So, find ways to separate child and parent and create dependency while the parent is absent. I try to spend lots of time with my kids to help correct state influence on my family.
hives
Still have hives. Going on day three I think. Against my best thoughts I took some benedryl. I have health concerns about it, but I was feeling wired and itchy. So, I broke my standing rule of no western meds. Slept well, but I’m groggy and still have these little things. All told there are probably 400 of these on me. At least my privates don’t have them. Currently just my knees and elbows.
I believe that the universe unfolds as it should. I think the hives are necessary to draw attention to something or release something from me. I’ll send it reiki and hope that I can achieve balance and health.
witness
I caught a whale vote so now I’m witness 7. This is tied for the all time high rank I’ve had. When I’m in the top ten I stop checking my position every day and just work. Feels good to be back here.
People say the witness rankings don’t change much. It usually happens at times like yesterday when the chain needs leaders and people who are actively here and watching. My node wasn’t the first one up, but it was top 5. I was happy to let Gandalf and Tim take the lead. They are Devs. I am not. I’m happy to let smart awesome people lead smartly and awesomely. I’m really impressed by the team and how we executed.
People many thought were solid haven’t updated yet. And so the rankings changed quite a bit. We will see how long this lasts. This gig is 24/7. Tim told me that when I was first starting.  It’s not all sunshine and producer rewards.
stake weighted voting
The witness system we have is pretty incredible. It’s hard to do 1 person one vote when bots and actors can fake things. I mean… you seen how many dead democrats vote? Fraud propels American democracy.
Stake weighted isn’t equal to all but at least it’s equal opportunity to all. I’m hoping one day Steem will have a better distribution on the platform, but even with my major concern this place did it’s job. The witness system is pretty incredible how 100+ people fight for 20 slots.
Bad actor did bad thing, chain stopped, steemit debugged, witnesses got it running. Some witnesses who weren’t present got replaced by backup witnesses. In hours we are back up and running. The state of Steem is strong. My home is good and despite its flaws we are chugging along. That feels like Independance to me. Many blessings of peace, abundance, and liberty to those who worked late into the night to get this baby running.
Your money is safe, your projects are safe, and arguably things are better. I’ll be here and I’ll be working. I mean, if I slip there are 80+ people with their hands raised saying “put me in coach.”
Steem isn’t just gonna moon itself. We collectively have more work to do, and I’m honored to do this work with you all.
Aggy
This page is synchronized from the post: ‘Happy 4th - musing from the airport.’


Heres a few scenarios:
Tap your space bar. The focused toggle changes. Submit the simple ajax form example and look at the console output data changes form data
React Input Toggle is most easilily installed as an npm package
npm install --save react-input-toggle
Each effect is definined using sass variables which can be overridden as necessary. Take a look at the top of each effect's commented sass file for what can be modified. Ex: Lima's
This component only requires a few properties,
effect
, labelPosition
, and label
.
All other props such as checked
or onChange
follow the same conventions and logic as any standard react form component. I.e. if you create a
Toggle
with a checked
prop of
true
then it's checked state will always be
true
. This is known as a controlled component. See the react
docs for further details.
Since a
Toggle
follows the same interface as a standard react
<input type="checkbox">
any event handlers such as
onChage
,
onFocus
, etc. have the same function signatures as a standard
react input. Additionly, props such as
disabled
,
data-*
, etc will correctly be passed down and be applied to
the underlying input component.
/* making a controlled component, passing down custom attributes,
setting default check state, event handlers, etc */
<Toggle checked={false} data-myattr={'attr'}
defaultChecked={false} onFocusCapture={this.func} >
| Property | Type | Default | Description |
|---|---|---|---|
effect
|
string
|
sierra
|
The style this element will take on. |
labelPosition
|
string
|
left
|
The prefered position of the label. Will collapse to
top or
bottom if there is not enough space available.
(uses flexbox layout model)
|
label
|
string
|
''
|
Text to be shown in the label. |


A Solo Dance Competition for all those feet tappers,hip-hoppers who can shake their legs and pull heavy crowd.
 This competition promises you breath-taking performances from the most talented of participants.
All forms of dances are allowed (classical, belly, Bollywood etc.)So here is the stage waiting for you.
Click here To Register..


Gardaí seize almost €1.5m of cocaine in Drogheda
by By Digital Desk staffGardaí have seized almost €1.5m worth of cocaine in Co. Louth.
Officers stopped a vehicle at the Donore Road Industrial Estate in Drogheda at around 12.35pm today and searched it.
They found packages containing 20kgs of cocaine with an estimated street value of €1.4m.
A man in his 30s was arrested at the scene and is being held at Drogheda Garda Station.
The arrest was carried out as part of Operation Stratus which is continuing.


Cacti - T. peruvianus
I bought the dried cactus from an online supplier. As preparation I ground up all the dried cuttings using a coffee grinder. This provided a nice fine powder which I could easily fill the required amount of gelatine capsules with.
3:00pm -- Ingested all the pills along with a lot of grapefruit juice. (no vomiting luckily)
4:00pm -- slight hint of an effect coming on but nothing definate.
4:50 - 5:20 -- The Trip starts...
6:00ish -- Trip is much stronger, and knowing that I had another hour or two (considering ingestion) of the mescaline peaking I started to worry slightly. At this level my thinking kept dashing from one thing to another, I couldnt concentrate but not in a lethargic way, instead too many emotions and feelings were there. It was as if 4 or 5 lines of thought were working but I kept shifting between them. However things such as drinking water, movement were easily performed. I found the STRONGEST effect I got from it was when listening to the radio, voices and music sounded completely different, certain aspects of voices were enhanced greatly and they seemed to speed up and slow down. Music itself sent me off into wild imagery (pleasent) that I could not put down as dream like or visually percieved but a strange combination of the two.
8:00 Peaking, I now began to feel a bit of anxiety mainly brought on by the constant brain work I had been doing, trying to understand the visuals and the sounds and everything had tired me out mentally and I felt I needed a break although I knew that wouldn't come soon.
9:00 By now I was certainly feeling mentally tired and needed a break so much so I went for the tranquilizers which I rarely touch out of principle. I gobbled down 40mg temazepam and 2mg clonazepam, which is quite a lot and only then after a while could I finally relax. Although I still felt tired and basically went straight to sleep.
Conclusion:
At this dosage I found mescaline to be less visual and much more emotional that is emotions that blended with my vision and hearing as well as touch.
The experience was well worth while but due to the length and inability (for me maybe) to relax into it I felt it was maybe a bit too much. I may one day try it again but not for a while.
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.


FlaneurFormView
public final class FlaneurFormView: UIView
View in charge of displaying form elements.
It is quite poorly designed as many problems arose late in the implementation:
IGListKit
-backed collection view is a terrible idea, it should be
a simple table viewSince
Since we design a form, we should skip reusable cells and just keep stong references of every cell: we wouldn’t need a cache anymoreobjc.io’s Swit Talks addressed the problems of reusable form components design in a series. It is a good inspiration to redesign this component.
Also, FlaneurImagePicker
is actually a form component library. It would probably make
sense that other form components belong to the same library, that should then be renamed
FlaneurForm
or something similar.
-
Undocumented
Declaration
Swift
public let collectionView: UICollectionView =
-
Initializes and returns a newly allocated navigation bar object with the specified frame rectangle.
Declaration
Swift
public override init(frame: CGRect)
Parameters
frame
The frame rectangle for the view, measured in points.
-
Returns an object initialized from data in a given unarchiver.
Declaration
Swift
public required init?(coder: NSCoder)
Parameters
coder
An unarchiver object.
-
Calls this exactly once.
Declaration
Swift
public func configure(viewController: UIViewController)
Parameters
viewController
the view controller presenting the form.
-
Adds a form element.
See also
FlaneurFormElement
Declaration
Swift
public func addFormElement(_ formElement: FlaneurFormElement, cacheValue: String? = nil)
Parameters
formElement
the form element to add to the form.
cacheValue
the cache value in case the form element is textual (this is terrible design).
-
Undocumented
Declaration
Swift
public func objects(for listAdapter: ListAdapter) -> [ListDiffable]
-
Undocumented
Declaration
Swift
public func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController
-
Undocumented
Declaration
Swift
public func emptyView(for listAdapter: ListAdapter) -> UIView?
-
Undocumented
Declaration
Swift
public func listAdapter(_ listAdapter: ListAdapter, willDisplay sectionController: ListSectionController)
-
Undocumented
Declaration
Swift
public func listAdapter(_ listAdapter: ListAdapter, didEndDisplaying sectionController: ListSectionController)
-
Undocumented
Declaration
Swift
public func listAdapter(_ listAdapter: ListAdapter, willDisplay sectionController: ListSectionController, cell: UICollectionViewCell, at index: Int)
-
Undocumented
Declaration
Swift
public func listAdapter(_ listAdapter: ListAdapter, didEndDisplaying sectionController: ListSectionController, cell: UICollectionViewCell, at index: Int)
-
Undocumented
Declaration
Swift
public func scrollCurrentFieldToVisible()
-
Undocumented
Declaration
Swift
public func nextElementShouldBecomeFirstResponder(cell: FlaneurFormElementCollectionViewCell)
-
Undocumented
Declaration
Swift
public func scrollToVisibleSection(cell: FlaneurFormElementCollectionViewCell)
-
Undocumented
Declaration
Swift
public func presentViewController(viewController: UIViewController)
-
Undocumented
Declaration
Swift
public func cacheValue(forLabel label: String) -> String?


Getting Started
Getting started is easy.
npm install easy-docs
ModuleClass
Class used to test jsdoc templating. This class will start very minimal and grow as various documenting use cases become apparent.
Parameters
| Name | Type | Description |
|---|---|---|
| opts | object | ModuleClass options. |
opts
| Name | Type | Description |
|---|---|---|
| prop1 | string | A very import property. |
| prop2 | string | A less important property. |
var module = new ModuleClass({
prop1: 'super duper important'
prop2: 'ehhh'
});
classMethod
A method that accepts some arguments and returns something.
Parameters
| Name | Type | Description |
|---|---|---|
| str | striing | A primitive string. |
| arr | Array | An array of some numbers. |
| obj | Object | Props and values yo. |
| callback | function | Callback after you have done something sweet. |
Returns
| Type | Description |
|---|---|
| string | A modified string. |
module.method('string', [0, 1], {
prop: 'value'
}, function () {});
moduleObject
Class used to test jsdoc templating. This class will start very minimal and grow as various documenting use cases become apparent.
objectMethod
Class used to test jsdoc templating. This class will start very minimal and grow as various documenting use cases become apparent.
Parameters
| Name | Type | Description |
|---|---|---|
| opts | object | moduleFunction options. |
opts
| Name | Type | Description |
|---|---|---|
| prop1 | string | A very import property. |
| prop2 | string | A less important property. |
moduleObject.method({
prop1: 'super duper important'
prop2: 'ehhh'
});
moduleFunction
Class used to test jsdoc templating. This class will start very minimal and grow as various documenting use cases become apparent.
Parameters
| Name | Type | Description |
|---|---|---|
| opts | object | moduleFunction options. |
opts
| Name | Type | Description |
|---|---|---|
| prop1 | string | A very import property. |
| prop2 | string | A less important property. |
moduleFunction({
prop1: 'super duper important'
prop2: 'ehhh'
});
License
The MIT License (MIT) Copyright (c) 2014 First Opinion
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Twitter CEO Sets Sight on African Bitcoin Market
by Osato Avan-NomayoTwitter and Square chief, Jack Dorsey, is meeting with African tech entrepreneurs as the bitcoin bull sets sight on the continent’s growing crypto industry.
Twitter CEO Heads to Africa
Dorsey is currently in Ghana after spending a few days in Nigeria meeting with tech entrepreneurs. Part of his visit has included mini bitcoin meetups with developers and startup founders pushing Bitcoin utilization in both countries.
If Google searches are anything to go by, then Africa is where it’s at. Data from Google Trends, shows Nigeria as having the highest BTC searches worldwide, over the past 12 months.
Twitter CEO bitcoin trends google
In fact, two other African countries — South Africa and Ghana also make up the top five. This high level of interest hasn’t, however, translated to concrete bitcoin adoption outside of the African cypherpunk scene just yet.
For Dorsey, this gap between interest and real-word utilization presents an opportunity for Square’s CashApp to penetrate the continent. Speaking during a town hall meeting at Techpoint in Lagos, the Square chief remarked,
I want to understand the challenges of starting a company here and figure out a way I can support. I want to live here for three to six months next year, full time, no travelling.
Some commentators say Dorsey’s approach highlights what constitutes the important aspects of mainstream adoption rather than the pursuit of ETFs and worthless blockchain applications.
African Mobile Money Market is Ripe for Bitcoin Adoption
According to World Bank figures, the majority of Sub-Saharan Africa remains unbanked. However, the continent has seen a massive penetration of mobile telecommunications technology.
Startups have also been able to leverage this telecoms boom to provide mobile money services even in rural areas without access to brick-and-mortar banking infrastructure. With such a buoyant mobile digital money market, bitcoin payment adoption seems like the next logical step.
Unlike officials in Asia and the West, governments in Sub-Saharan Africa haven’t created administrative roadblocks for crypto adoption. Save for the usual talk of risks, startups operating in the industry have a much clearer field.
Some crypto companies seem to be alive to this reality and are already seeking ways to leverage the potential in the African digital market. As previously reported by Bitcoinist, Binance added the Nigerian Naira as its first ever fiat trading pair.
Images via Google Trends and Twitter @jacobkostecki.
The Rundown


<input id="namingConainerId:_:myForm:lastName" ... />
from the DOM.If the issue still exists, then form submission will succeed and you will see the global FacesMessage "Hello John null"
Otherwise, if the issue is fixed, You should see "Validation Error: Value is required" for the lastName field.