2 Data processing
Let’s process the raw data and get them to a format that we can work with for the analysis. The study has three raw data files:
personality_raw.csv
is the survey participants filled out at the beginning of the study, reporting personality traitsdiary_raw.csv
is the end of day survey participants filled out during the diary part of the studyscreen_time_raw.csv
is the objective screen time data participants reported
2.1 Personality data
The data are on the OSF.
You can download them if you set the code chunk below to eval=TRUE
.
Downloading only works when the OSF project is public.
If it isn’t during peer review, you’ll need to paste the data files from the OSF to the data/
folder manually.
# create directory
dir.create("data/", FALSE, TRUE)
# download models
osf_retrieve_node("https://osf.io/7byvt/") %>%
osf_ls_nodes() %>%
filter(name == "data") %>%
osf_ls_files(
.,n_max = Inf
%>%
) osf_download(
.,path = here("data"),
progress = FALSE
)
## # A tibble: 4 x 4
## name id local_path meta
## <chr> <chr> <chr> <list>
## 1 diary_raw.csv 603e5635441575030c586bc7 data/diary_raw.csv <named list [3]>
## 2 personality_raw.csv 603e5635035cf7031cc86382 data/personality_raw.csv <named list [3]>
## 3 processed_data.rds 603e56364415750312587b3a data/processed_data.rds <named list [3]>
## 4 screen_time_raw.csv 603e56374415750312587b48 data/screen_time_raw.csv <named list [3]>
Let’s load the personality data.
<- read_csv(here("data", "personality_raw.csv")) personality_raw
Qualtrics names aren’t very informative, so I give some sensible variable names (although this data set has mostly meaningful variable names).
Also, there are variables (i.e., anything starting with afi
to selfreflect
) that were part of a different study, which is why I don’t include them here.
Note that I don’t want to change the raw data object, so I’ll keep using personality
as a new object from here on.
<-
personality %>%
personality_raw select(
# meta data
start_date = StartDate,
end_date = EndDate,
progress = Progress,
duration = Duration__in_seconds_,
finished = Finished,
recorded_date = RecordedDate,
id = study_id,
date,
# basic psychological need satisfaction trait
bpns_ = starts_with("bpns"),
# big five
big_five_ = starts_with("bfi"),
# demographics
gender,gender_entry = gender_3_TEXT,
age = Q42,
ethnicity_american_indian = ethnicity_1,
ethnicity_asian = ethnicity_2,
ethnicity_island = ethnicity_3,
ethnicity_black = ethnicity_4,
ethnicity_white = ethnicity_5,
ethnicity_hispanic = ethnicity_6,
ethnicity_multi = ethnicity_7
)
Next, I make sure those variables have the correct variable type.
I’ll also recode factor levels so that labels are readable.
Note that participants filled in their age from a dropdown menu to prevent typos.
The dropdown went from age 18 (1
) to 30+ (13
).
Nobody was older than thirty, so I’ll recode age as well.
<-
personality %>%
personality mutate(
id = paste0("pp_", id), # add pp for participant just so later I don't mistake the id variable for a count
across( # turn those two into factors
c(finished, id, gender),
as.factor
),finished = fct_recode(
finished,"yes" = "1",
"no" = "0"
),gender = fct_recode(
gender,"male" = "1",
"female" = "2",
"other" = "3"
),age = age + 17
)
I see that ethnicity was multiple choice although “multiracial” is an answer option. So I think it makes more sense to combine this all into one variable. That required quite a lot of code, but was still less problematic than transforming the ethnicity variables to long format. I took the following steps:
- check who reported multiple ethnicities
- those who did get an
NA
on all other ethnicity variables - recoded the variables from numeric to containing the ethnicity factor level and coalesce
<-
personality %>%
personality mutate(
multiple = rowSums(select(., starts_with("ethnicity")), na.rm = TRUE), # check who reported multiple ethnicities
# those with multiple get NA for all other ethnicity variables
across(
c(ethnicity_american_indian:ethnicity_hispanic),
~ case_when(
> 1 ~ NA_real_,
multiple TRUE ~ .
)
),
# turn into character which makes recoding below easier
across(
c(ethnicity_american_indian:ethnicity_hispanic),
as.character
),
# recode the individual variables
ethnicity_american_indian = if_else(ethnicity_american_indian == 1, "American Indian/Alaska Native", NA_character_),
ethnicity_asian = if_else(ethnicity_asian == 1, "Asian", NA_character_),
ethnicity_island = if_else(ethnicity_island == 1, "Native Hawaiian or Other Pacific Islander", NA_character_),
ethnicity_black = if_else(ethnicity_black == 1, "Black or African American", NA_character_),
ethnicity_white = if_else(ethnicity_white == 1, "White", NA_character_),
ethnicity_hispanic = if_else(ethnicity_hispanic == 1, "Hispanic or Latino", NA_character_),
ethnicity_multi = if_else(multiple > 1, "Multiracial", NA_character_),
# coalesce them (coalesce doesn't work with .select helpers, so needed to type the variables out)
ethnicity = as.factor(
coalesce(
ethnicity_american_indian,
ethnicity_asian,
ethnicity_island,
ethnicity_black,
ethnicity_white,
ethnicity_hispanic,
ethnicity_multi
)
)%>%
) select(start_date:age, ethnicity)
Then I remove those cases without an id
(aka test runs) and those with an id
but not other entries.
The latter are probably no-shows.
Note: In the earlier versions of this script, I excluded per data set, which made it hard for reporting exact exclusions in the final paper.
For example, at this point I don’t know whether someone I exclude here even participated in the diary part of the study.
Therefore, I save each exclusion criterion in a separate object and inspect how many people we actually need to exclude later in the data merging section.
# remove test run
<-
personality %>%
personality filter(id != "pp_NA")
<-
personality_exclusions_1 %>%
personality filter(is.na(start_date)) %>%
pull(id)
| na_count_row | n |
|---|---|
| 0 | 1 |
| 1 | 246 |
| 2 | 29 |
| 3 | 5 |
| 4 | 2 |
| 7 | 1 |
| 9 | 2 |
| 25 | 1 |
| 49 | 4 |
| 74 | 1 |
| 81 | 10 |
I’ll exclude the latter.
# exclude those with > 15 missing values (which identifies empty rows)
<-
personality_exclusions_2 %>%
personality mutate(
na_count_row = rowSums(is.na(.))
%>%
) filter(na_count_row >70) %>%
pull(id)
Alright, time to construct the means for the scales. But first, I check data quality by seeing whether there are instances of “straightlining” (i.e., choosing the same response option for all items of a scale). We also had attention checks in the survey.
Let’s have a look at those attention checks. For itembpns_25
participants had to choose 2
as a response and for item big_five_45
they had to choose 5
.
When we check Table 2.2, we see that 5 participants didn’t pass both attention checks.
|
|
|
I’ll exclude those participants because I don’t think we can trust their data.
<-
personality_exclusions_3 %>%
personality filter(bpns_25 != 2 & big_five_45 != 5) %>%
pull(id)
Next, I check for straightlining by inspecting the variance per daily survey on the BPNS and BF scales. Turns out that it’s not super straightforward to compute variance per row, found help here.
<-
personality %>%
personality rowwise() %>%
mutate(
bpns_sd = sd(
c_across(starts_with("bpns")),
na.rm = TRUE
),big_five_sd = sd(
c_across(starts_with("big_five")),
na.rm = TRUE
)%>%
) unnest(cols = c())
Those two are already captured by the exclusion criteria above (I checked manually, but I’ll still save them in an object).
<-
personality_exclusions_4 %>%
personality filter(bpns_sd == 0 | big_five_sd == 0) %>%
pull(id)
Alright, now we can aggregate the individual items to scale scores. Some of those items are reverse-coded (see the codebook for details). I’ll code all scales such that a higher scores means scoring more positively on that scale.
<-
personality %>%
personality mutate(
across(
c(
:bpns_8,
bpns_5:bpns_15,
bpns_13:bpns_25,
bpns_21
),function(.) 8 - .
),across(
c(
big_five_2,
big_five_6,
big_five_8,
big_five_9,
big_five_12,
big_five_18,
big_five_21,
big_five_23,
big_five_27,
big_five_31,
big_five_37,
big_five_43
),function(.) 6 - .
) )
Now I create the scales by taking the mean of the respective items. Note that I remove missing values in computing row means to ignore the occasional missing value. (For those with missing values throughout, see next code chunk.)
<-
personality %>%
personality mutate(
# trait needs
autonomy_trait = rowMeans(select(., bpns_1:bpns_8), na.rm = TRUE),
competence_trait = rowMeans(select(., bpns_9:bpns_16), na.rm = TRUE),
relatedness_trait = rowMeans(select(., bpns_17:bpns_24), na.rm = TRUE),
# big five
extraversion = rowMeans(
select(
.,
big_five_1,
big_five_6,
big_five_11,
big_five_16,
big_five_21,
big_five_26,
big_five_31,
big_five_36
),na.rm = TRUE
),agreeableness = rowMeans(
select(
.,
big_five_2,
big_five_7,
big_five_12,
big_five_17,
big_five_22,
big_five_27,
big_five_32,
big_five_37,
big_five_42
),na.rm = TRUE
),conscientiousness = rowMeans(
select(
.,
big_five_3,
big_five_8,
big_five_13,
big_five_18,
big_five_23,
big_five_28,
big_five_33,
big_five_38,
big_five_43
),na.rm = TRUE
),neuroticism = rowMeans(
select(
.,
big_five_4,
big_five_9,
big_five_14,
big_five_19,
big_five_24,
big_five_29,
big_five_34,
big_five_39
),na.rm = TRUE
),openness = rowMeans(
select(
.,
big_five_5,
big_five_10,
big_five_15,
big_five_20,
big_five_25,
big_five_30,
big_five_35,
big_five_40,
big_five_41,
big_five_44
),na.rm = TRUE
) )
Last, some participants didn’t fill out the Big Five items, so they haven an NaN
entry for those scales now.
I’ll turn that into an NA
value
<-
personality %>%
personality mutate(
across(
c(autonomy_trait:openness),
~ na_if(.x, "NaN")
) )
2.2 Diary data
Let’s load and inspect the diary data.
# load data
<- read_csv(here("data", "diary_raw.csv")) diary_raw
Qualtrics names aren’t very informative, so I give some sensible variable names.
Again, there are many variables (i.e., anything before Q21-1
) that were part of a different study, which is why I don’t include them here.
Like before, I don’t want to change the raw data object, so I’ll keep using diary
as a new object from here on.
<-
diary %>%
diary_raw select(
# meta data
start_date = StartDate,
end_date = EndDate,
progress = Progress,
duration = Duration__in_seconds_,
finished = Finished,
recorded_date = RecordedDate,
id = study_id,
day = Day,
date = Q27,
# social media subjective estimates
hours_subjective = Q21_1,
minutes_subjective = Q21_2,
pickups_subjective = Q22_1,
notifications_subjective = Q23_1,
# arousal
low_positive_peaceful = Q24_1,
low_positive_calm = Q24_2,
low_positive_related = Q24_3,
high_negative_anxious = Q24_4,
high_negative_jittery = Q24_5,
high_negative_tense = Q24_6,
high_positive_happy = Q24_7,
high_positive_energized = Q24_8,
high_positive_excited = Q24_9,
low_negative_sluggish = Q24_10,
low_negative_sad = Q24_11,
low_negative_gloomy = Q24_12,
# autonomy need satisfaction
autonomy_ = Q25_1:Q25_4,
# competence need satisfaction
competence_ = Q25_5:Q25_8,
# relatedness need satisfaction
relatedness_ = Q25_9:Q25_12,
# experiences
satisfied = Q30_1,
boring = Q30_2,
stressful = Q30_3,
enjoyable = Q30_4
)
Next, I make sure those variables have the correct variable type.
I’ll also recode factor levels so that labels are readable.
Note that day
goes from 1
to 5
.
All participants started on a Monday, which is why I turn day
into a factor and reorder the levels.
<-
diary %>%
diary mutate(
id = paste0("pp_", id), # add pp for participant just so later I don't mistake the id variable for a count
across( # turn those two into factors
c(finished, id, day),
as.factor
),finished = fct_recode(
finished,"yes" = "1",
"no" = "0"
),day = fct_recode(
day,"monday" = "1",
"tuesday" = "2",
"wednesday" = "3",
"thursday" = "4",
"friday" = "5"
) )
Then I identify all empty rows (i.e., rows without a start date, so people who have placeholder id
, but didn’t participate on that day).
<-
diary_exclusions_1 %>%
diary filter(is.na(start_date)) %>%
select(id, day)
NA
s there are per row in Table 2.3.
Most participants filled out everything, but a couple of them have basically empty rows (e.g., those with 30 or 40 missing values per row).
| na_count_row | n |
|---|---|
| 0 | 1072 |
| 1 | 49 |
| 2 | 16 |
| 3 | 3 |
| 4 | 1 |
| 6 | 1 |
| 8 | 1 |
| 9 | 2 |
| 16 | 1 |
| 20 | 1 |
| 23 | 1 |
| 28 | 2 |
| 32 | 24 |
| 39 | 336 |
I manually inspected those with more than 15 missing values and neither of them even finished any of the scales. Therefore, I’ll exclude them here.
# exclude those with > 15 missing values
<-
diary_exclusions_2 %>%
diary mutate(
na_count_row = rowSums(is.na(.))
%>%
) filter(na_count_row > 15) %>%
mutate(id = droplevels(id)) %>%
select(id, day)
For notifications, it’s hard to argue that it’s unrealistic that participants thought they got several hundred of them.
So I will leave those unchanged.
However, there are several outliers in hours_subjective
and minutes_subjective
.
I manually inspected those cases and it’s hard to tell whether participants just mixed up hours and minutes or whether their entry is indeed not meaningful.
One participant filled in 50h and 500min.
Another 40h.
For those two, I’ll set their subjective values to NA
.
One participant filled in 5h and 86min.
The minutes entry might have been a typo, but it’s hard to tell what the participant meant, so I’ll set that to NA
as well.
<-
diary %>%
diary mutate(
hours_subjective = case_when(
> 24 | minutes_subjective > 60 ~ NA_real_,
hours_subjective TRUE ~ hours_subjective
),minutes_subjective = if_else(
> 60,
minutes_subjective NA_real_,
minutes_subjective
) )
Next, I check data quality further by seeing whether there are instances of “straightlining.” For that, I check the variance per daily survey on the well-being scale, need satisfaction, and experiences.
<-
diary %>%
diary rowwise() %>%
mutate(
well_being_sd = sd(
c_across(low_positive_peaceful:low_negative_gloomy),
na.rm = TRUE
),needs_sd = sd(
c_across(autonomy_1:relatedness_4),
na.rm = TRUE
),experiences_sd = sd(
c_across(satisfied:enjoyable),
na.rm = TRUE
)%>%
) unnest(cols = c())
In general, it’s not uncommon to select the same answer, especially for well-being measures. However, I’d be suspicious of those participants who straightlined for more than one scale (particularly the need satisfaction scale because it has quite a lot of items.) I’ll check how many surveys there are that have zero variance across those scales and how many participants there are who have at least one straightlining instance in more than 50% of their surveys.
<-
diary %>%
diary mutate(
zero_variances = rowSums(
select(., ends_with("_sd")) == 0, # count instances of zero variance across the three scales
na.rm = TRUE
) )
| zero_variances | n | percent |
|---|---|---|
| 0 | 1440 | 0.9536424 |
| 1 | 29 | 0.0192053 |
| 2 | 21 | 0.0139073 |
| 3 | 20 | 0.0132450 |
| id | total_surveys | total_straightline_surveys | percentage |
|---|---|---|---|
| pp_172 | 4 | 3 | 0.75 |
| pp_121 | 5 | 3 | 0.60 |
| pp_164 | 5 | 3 | 0.60 |
| pp_169 | 5 | 3 | 0.60 |
| pp_103 | 2 | 1 | 0.50 |
| pp_168 | 2 | 1 | 0.50 |
| pp_290 | 2 | 1 | 0.50 |
| pp_154 | 5 | 2 | 0.40 |
| pp_198 | 5 | 2 | 0.40 |
| pp_35 | 5 | 2 | 0.40 |
I will exclude those participants and then surveys with more than one instance of straightlining.
<-
diary_exclusions_3 c("pp_172", "pp_121", "pp_164", "pp_169", "pp_103", "pp_168", "pp_290")
| zero_variances | n | percent |
|---|---|---|
| 0 | 1072 | 0.9571429 |
| 1 | 20 | 0.0178571 |
| 2 | 14 | 0.0125000 |
| 3 | 14 | 0.0125000 |
Alright, now we can aggregate the individual items to scale scores. Some of those items are reverse-coded. Namely, the third and fourth item for the need satisfaction subscales are reverse coded, as are all negative arousal items (if we want to create a score that shows higher well-being). See codebook for details.
# reverse code need items and arousal
<-
diary %>%
diary mutate(
across(
c(ends_with("_3"), ends_with("_4")),
function(.) 8 - .
),across(
contains("negative"),
function(.) 6 - .
) )
I create the scales by taking the mean of the respective items.
I also create a social_media_subjective
measure by combining hours and minutes of estimated social media time.
<-
diary %>%
diary mutate(
social_media_subjective = hours_subjective * 60 + minutes_subjective,
well_being_state = rowMeans(select(., low_positive_peaceful:low_negative_gloomy), na.rm = TRUE),
autonomy_state = rowMeans(select(., contains("autonomy")), na.rm = TRUE),
competence_state = rowMeans(select(., contains("competence")), na.rm = TRUE),
relatedness_state = rowMeans(select(., contains("relatedness")), na.rm = TRUE)
)
Further, participants’ first day of participation was always a Monday. Specifically, three days in April 2019: the 15th, 22nd, 29th. Let’s check whether all of them indeed have their first day on one of those days.
Table 2.7 shows all day one surveys which were not recorded on one of those three dates. Indeed, everyone opened their first survey on one of the three start days. Some participants opened/recorded their answers right after midnight, which is fine.| id | start_date | recorded_date | duration | day |
|---|---|---|---|---|
| pp_21 | 2019-04-30 00:35:48 | 2019-04-30 00:57:14 | 1284 | monday |
| pp_61 | 2019-04-29 16:59:21 | 2019-05-06 17:00:41 | 72 | monday |
| pp_71 | 2019-04-22 16:01:29 | 2019-04-24 11:00:01 | 154711 | monday |
| pp_110 | 2019-04-22 20:16:35 | 2019-04-23 00:30:27 | 15231 | monday |
| pp_120 | 2019-04-23 00:08:15 | 2019-04-23 00:20:35 | 739 | monday |
| pp_192 | 2019-04-15 20:36:47 | 2019-04-16 00:27:47 | 13859 | monday |
| pp_201 | 2019-04-30 00:27:10 | 2019-04-30 00:52:59 | 1548 | monday |
| pp_211 | 2019-04-22 17:24:37 | 2019-04-23 12:13:59 | 67761 | monday |
| pp_257 | 2019-04-30 00:52:05 | 2019-04-30 01:21:55 | 1789 | monday |
| pp_265 | 2019-04-29 23:28:18 | 2019-04-30 01:34:43 | 7584 | monday |
| pp_275 | 2019-04-29 16:20:39 | 2019-05-06 16:31:47 | 648 | monday |
pp_71
took two days to respond to a survey.
| id | start_date | recorded_date | duration | day |
|---|---|---|---|---|
| pp_71 | 2019-04-22 16:01:29 | 2019-04-24 11:00:01 | 154711 | monday |
I guess it’s normal that participants open the survey late, forget it, and fill it out when they next day when they wake up. Because they’re students, waking up might be quite late, so I’ll check in Table 2.9 how many of them responded to a survey later than 10am the next day. Two participants were really late (i.e., responded after noon).
## Joining, by = c("id", "day")
## Joining, by = c("id", "day")
| id | start_date | recorded_date | duration | day |
|---|---|---|---|---|
| pp_53 | 2019-04-18 16:11:51 | 2019-04-19 10:08:16 | 64584 | thursday |
| pp_71 | 2019-04-22 16:01:29 | 2019-04-24 11:00:01 | 154711 | monday |
| pp_98 | 2019-04-30 17:21:21 | 2019-05-01 12:03:12 | 67310 | tuesday |
| pp_161 | 2019-05-02 18:15:49 | 2019-05-03 10:05:25 | 56975 | thursday |
| pp_162 | 2019-04-30 22:00:37 | 2019-05-01 10:52:15 | 46297 | tuesday |
| pp_211 | 2019-04-22 17:24:37 | 2019-04-23 12:13:59 | 67761 | monday |
| pp_211 | 2019-04-23 23:40:53 | 2019-04-24 10:30:27 | 38972 | tuesday |
| pp_244 | 2019-04-19 18:45:44 | 2019-04-20 11:52:12 | 61587 | friday |
I manually checked the data from all those participants who filled out surveys so late that two surveys were recorded on the same day.
pp_71
responded to the Monday survey on Wednesday, in addition to the “regular” Wednesday survey.
For that reason, we can’t know whether day
one refers to Monday or Tuesday.
All other participants are fine: They sometimes recorded their response late, but their response pattern shows no indication that they couldn’t refer to a clear day in their response.
Therefore, I remove the day
one survey of pp_71
because we can’t tell to which day it refers, but leave the rest as is.
<-
diary_exclusions_4 tibble(id = "pp_71", day = "monday")
2.3 Screen time data
Load the screen time data.
<- read_csv(here("data", "screen_time_raw.csv")) screen_time_raw
Alright, the data are extremely wide because of the Qualtrics format. There are 220 variables in total. The data look like this:
- Total time over the past week of social media, plus total time per day (
Q2_1
toQ10_2
) - Typing in the top ten social networking media (
Q4_1
toQ4_10
) - Then participants filled in 13 items for each of those ten apps, first total time and notifications for the week for that app, then hours and minutes per day for that app (total 130 items,
Q3_1
toQ76_2
) - Then participants reported six items per each of the ten apps, the first of which was overall pickups in the past week, followed by pickups for each day of the week (
Q17_1_TEXT
toQ17_10_5
)
Before turning the data into long format, I need to give some sensible variables names. However, manually renaming all variables is a real pain. So I’ll create the names systematically and store them in a vector, then assign them to the variables.
# define days
<-
days c(
"monday",
"tuesday",
"wednesday",
"thursday",
"friday"
)
# the list of apps
<-
apps paste0(
rep("app_", 10),
1:10
)
# add hours and minutes to apps
<-
apps_times paste0(
rep(apps, each = 6*2),
"_",
c("hours", "minutes")
)
# the overall time per week and day
<-
names1 paste0(
rep(c("hours_total_", "minutes_total_"),6),
rep(c("week", days), each = 2)
)
# now app, minutes, hours, per day
<-
names2 paste0(
apps_times,"_",
rep(c("week", days), each = 2)
)
# notifications per day
<-
names3 paste0(
apps,"_",
"notifications",
"_week"
)
# pickups per week and day
<-
names4 paste0(
rep(apps, each = 6),
"_pickups_",
rep(c("week", days), 6)
)
Then I apply those names. Once more, I use a new object and don’t overwrite the raw data.
# let's rename
<-
screen_time %>%
screen_time_raw
# meta-data
rename(
start_date = StartDate,
end_date = EndDate,
progress = Progress,
duration = Duration__in_seconds_,
finished = Finished,
recorded_date = RecordedDate,
id = study_id
%>%
)
# the overall time per week and day
rename_with(
~ names1,
:Q10_2
Q2_1%>%
)
# the top ten apps
rename(
app_ = Q4_1:Q4_10
%>%
)
# now rename all app minutes and hours per day
rename_with(
~ names2,
c( # except the notifications because they don't fit the pattern
:Q76_2,
Q3_1-Q11_1,
-Q22_1,
-Q78_1,
-Q29_1,
-Q43_1,
-Q36_1,
-Q50_1,
-Q57_1,
-Q64_1,
-Q71_1
)%>%
)
# the past week notifications per app
rename_with(
~ names3,
c(
Q11_1,
Q22_1,
Q78_1,
Q29_1,
Q43_1,
Q36_1,
Q50_1,
Q57_1,
Q64_1,
Q71_1
)%>%
)
# rename pickup variables
rename_with(
~ names4,
:Q17_10_5
Q17_1_TEXT%>%
)
# only keep variables of interest
select(
-Status
)
# remove name objects (they were only temp files)
rm(apps, apps_times, days, names1, names2, names3, names4)
Before I assign variables types and factor levels, I saw that, for some reason, the past week’s number of pickups for each app have text entries, not numerical (i.e., "twenty one"
instead of 21
).
I know that the english
package can translate numbers to words, but not the other way around.
Thank god, someone has written a function for this, see full details here.
The function is in the Setting up chapter.
Note that this word2num
function doesn’t work well with the word “and.”
For example, "three hundred and eleven"
turns into 611
, but "three hundred eleven"
turns into the correct 311
.
Therefore, I first remove all “and”s from those variables, then apply the function.
Similarly, I’ll replace all “a” with “one” (e.g., “a hundred” to “one hundred”).
One participant also replied with a string (that they access facebook via their browser), so I’ll set that to NA
.
<-
screen_time %>%
screen_time mutate(
across(
ends_with("pickups_week"),
~ case_when(
== "NA because accessed Facebook through Safari" ~ NA_character_,
.x == "NA because accessed Twitter through Safari" ~ NA_character_,
.x TRUE ~ .x
)
),across(
ends_with("pickups_week"),
~ str_remove(.x, "and")
),across(
ends_with("pickups_week"),
~ str_replace(.x, "A ", "one ")
)%>%
) rowwise() %>%
mutate(
across(
ends_with("pickups_week"),
word2num
),across(
ends_with("pickups_week"),
unlist
)%>%
) unnest(cols = c())
Next, I assign correct variable types and factor levels.
<-
screen_time %>%
screen_time mutate(
id = paste0("pp_", id),
across( # turn those two into factors
c(finished, id),
as.factor
),finished = fct_recode(
finished,"yes" = "1",
"no" = "0"
) )
Then I exclude empty rows.
The data set has all participant numbers even when they didn’t participate, so I’ll identify those without a start date as well as those who didn’t fill in app_1
, which means they have empty rows other than the meta-data.
<-
screen_time_exclusions_1 %>%
screen_time filter(is.na(start_date) | is.na(app_1)) %>%
mutate(id = droplevels(id)) %>%
pull(id)
At this point, the data set has measures on two levels: per app and time frame (day, full week), and the total times across all apps per day.
I think it’s easiest to separate the data.
The per app data are only informative for plotting and descriptives, but the actual data we’re interested in are the total times summed across all apps.
So I’ll first get the per data app (excluding empty rows temporarily from screen_time
).
Note that I add the names of the apps in a separate step and then calculate the objective social media time.
# turn app data long
<-
apps_long %>%
screen_time filter(!is.na(start_date)) %>%
filter(!is.na(app_1)) %>%
mutate(id = droplevels(id)) %>%
select(
:id,
start_date:app_10_pickups_friday
app_1_hours_week%>%
) pivot_longer(
cols = c(app_1_hours_week:app_10_pickups_friday),
names_to = c(
"app",
"rank",
"measure",
"time_frame"
),names_sep = "_"
%>%
) pivot_wider( # then spread the measure variable which now contains hours, minutes, notifications, pickups
names_from = "measure",
values_from = "value"
%>%
) select(-app) # redundant
# get the names of the apps
<-
app_names %>%
screen_time filter(!is.na(start_date)) %>%
filter(!is.na(app_1)) %>%
mutate(id = droplevels(id)) %>%
select(
id,:app_10
app_1%>%
) pivot_longer(
-id,
names_to = c("app", "rank"),
names_sep = "_"
%>%
) select(-app) %>% # redundant
rename(
app = value # contains name of app
)
# add them to the long data set
<-
apps_long left_join(
apps_long,
app_names,by = c("id", "rank")
%>%
) relocate(
app, .after = rank
%>%
)
# if someone only filled in minutes, but not hours, turn hours to 0
mutate(
hours = case_when(
is.na(hours) & is.na(minutes) ~ NA_real_,
is.na(hours) & !is.na(minutes) ~ 0,
TRUE ~ hours
),
# when someone only filled in hours, but not minutes, turn minutes to 0
minutes = case_when(
is.na(hours) & is.na(minutes) ~ NA_real_,
!is.na(hours) & is.na(minutes) ~ 0,
TRUE ~ minutes
),
# total time
social_media_objective = hours * 60 + minutes
)
Then I get the total times across all apps in the long format. Note that participants reported their screen time on the weekend. Thus, their reports for week will not be identical with the sum of Monday to Friday, because the screen time feature measures time on the weekend as well (aka additional screen time measured from the end of Friday until the moment they reported their weekly screen time).
# get total screen time (of all social media apps in long format)
<-
totals_long %>%
screen_time filter(!is.na(start_date)) %>%
filter(!is.na(app_1)) %>%
mutate(id = droplevels(id)) %>%
select(
id,:minutes_total_friday
hours_total_week%>%
) pivot_longer(
-id,
names_to = c(
"measure",
"total",
"time_frame"
),names_sep = "_"
%>%
) select(-total) %>% # redundant
pivot_wider( # spread hours and minutes
names_from = "measure",
values_from = "value"
%>%
)
# same as above: if one of the two measures (hours or minutes) has an entry and the other is NA, we set that NA to 0
mutate(
hours = case_when(
is.na(hours) & is.na(minutes) ~ NA_real_,
is.na(hours) & !is.na(minutes) ~ 0,
TRUE ~ hours
),
# when someone only filled in hours, but not minutes, turn minutes to 0
minutes = case_when(
is.na(hours) & is.na(minutes) ~ NA_real_,
!is.na(hours) & is.na(minutes) ~ 0,
TRUE ~ minutes
),
# total time
social_media_objective = hours * 60 + minutes
)
The totals_long
is the data set of interest because it has total screen time per day, which we can match with the diary data.
Thus, to arrive at the final sample size, we’ll only keep participants who have data in the diary
data set.
For merging, we’ll need to exclude those participants in totals_long
who don’t have a match in diary
.
But first, I check how much the sum of total time across apps per day in total_long
converges with the sum of time across all apps per day in apps_long
.
There will definitely be differences, simply because participants have more chances to make typos when reporting the individual apps per day (in apps_long
) compared to reporting the overall time across all apps once per day (in total_long
).
Also, participants will occasionally skip an individual app per day rating.
Below, I get the total time per day across all ten apps and then join that estimate with the data set containing the total times (total_long
).
Afterwards, per day, I see how much the two variables differ.
# get total time across apps per day
<-
apps_aggregated %>%
apps_long group_by(id, time_frame) %>%
filter(time_frame != "week") %>% # no week
summarise(total_time = sum(social_media_objective, na.rm = TRUE))
# join with total times
<-
compare left_join(
%>%
totals_long filter(time_frame != "week"),
apps_aggregated%>%
)
# and compute a deviance score
mutate(
difference = social_media_objective - total_time
)
Overall, the two sums of use across apps and days are highly similar, with a mean difference of M = 4.09, SD = 17.4 and an extremely high correlation, r = 0.98.
There were some missing values in the total social media time per day that participants reported. I check who has missing data on any of the weekdays in thetotals_long
data set.
We can check whether those participants have reported individual app use for that day and use an aggregate over apps on that day as a substitute, given their high correlation.
In other words: When participants forgot to report their overall social media use for a day, but reported use for all social media apps they used on that day, we can just use the sum of those social media apps as a replacement for overall social media use.
However, we see in 2.10 that all participants reported social media screen time across all days, so no need for imputation.
| id | time_frame | hours | minutes | social_media_objective | total_time | difference |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Before I merge all data sets, I need to add the objective notifications and pickups (currently in apps_long
) to the totals_long
data set.
Note that at the time of the study, iOS screen time wouldn’t report notifications for app per day, only for the past week.
Therefore, the weekly notifications have the same caveat as the weekly screen time: they will include a couple of notifications that participants received on the day they retrospectively reported their objective use.
For pickups, as with screen time, we can sum up all days to get an accurate measure of week’s pickups.
I’ll sum up both pickups and notifications over participant.
Pickups will be per day, but notifications only per week.
I then add pickups to the totals_long
data set.
Notifications I’ll add later during merging (because they are not aggregated per day).
# get total pickups across apps per day
<-
pickups_aggregated %>%
apps_long group_by(id, time_frame) %>%
filter(time_frame != "week") %>% # no week
filter(!is.na(pickups)) %>% # exclude missing values (if I do na.rm = T in sum below it will result in zeros to sum NAs)
summarise(pickups_objective = sum(pickups))
# get notifications across apps per participant
<-
notifications_aggregated %>%
apps_long group_by(id) %>%
summarise(weekly_notifications = sum(notifications, na.rm = TRUE))
# add pickups to totals_long
<-
totals_long left_join(
totals_long,
pickups_aggregated,by = c("id", "time_frame")
)
2.4 Merge data sets
Finally, we can merge the three data sets. Before I do any merging, I’ll check out the number of data points per data set and the ones they have in common before I count exclusions. This is mostly for reporting in the paper.
# number of participants who took initial survey (take out empty rows)
%>%
personality filter(!id %in% personality_exclusions_1) %>%
pull(id) -> personality_n
length(personality_n)
## [1] 292
# number of those who also participated in diary part
%>%
diary anti_join(., diary_exclusions_1) -> diary_n
## Joining, by = c("id", "day")
length(unique(diary_n$id))
## [1] 275
# number of those who came back to report screen time
%>%
screen_time filter(!id %in% screen_time_exclusions_1) %>%
pull(id) -> screen_time_n
length(screen_time_n)
## [1] 97
The diary
data set is the “base” because it has our variables of interest and the correct time structure.
To that data set we add the objective social media measures from the totals_long
data set.
The identifier for a survey are the participant id
and the day
on which they filled out a survey/for which they reported objective use.
Note that we omit the meta-data from totals_long
(e.g., start_date
) because they are different from the meta-data of diary
.
We also only keep the variables of interest from here on, meaning I’ll exclude some variables that aren’t informative.
<-
dat left_join(
# the diary data with only relevant variables
%>%
diary select(
duration_diary = duration, # so that we can get filling out times for each data set
:day,
id:enjoyable, # don't need individual minutes and hours anymore
pickups_subjective:relatedness_state
social_media_subjective
),
# the objective totals with only relevant variables
%>%
totals_long filter(time_frame != "week") %>%
rename(
day = time_frame
%>%
) select(id, day, social_media_objective, pickups_objective),
# joining by the two identifiers
by = c("id", "day")
)
The merging above kept all cases of diary
and added variables from totals_long
when there was a match, otherwise setting the new variables to NA
.
Therefore, I remove all cases which have NA
on the added variables to get to our final sample.
(There were no missings in the social_media_objective
variable.)
In other words, this removes those participants who didn’t fill out the screen time survey.
<-
dat %>%
dat filter(!is.na(social_media_objective))
For descriptive information, I’ll also add the survey duration of the screen time data.
<-
dat left_join(
dat,%>%
screen_time select(id, duration) %>%
rename(
duration_screen_time = duration
),by = "id"
)
Okay, then I add the personality variables.
Again, dat
is the “master” and we add personality variables (aka traits from personality
), omitting variables that aren’t of interest.
<-
dat left_join(
dat,%>%
personality select(
duration_personality = duration,
id,:openness
bpns_1
),by = "id"
)
Then, I add the notifications over one week as a constant.
<-
dat left_join(
dat,
notifications_aggregated,by = "id"
)
Alright, only keeping those who had screen time measures already removed a large number of cases, some of them were part of the exclusions for both the personality
and the diary
parts.
I now apply all exclusions (if necessary) to get to the final data set.
Note that I don’t exclude those in diary_exclusions_2
after all: Those are the ones who didn’t fill in an experience sampling survey, but all of them still have personality scores and the retrospective screen time estimates.
## personality
# nobody left who didn't fill in the personality survey
unique(dat$id %in% personality_exclusions_1)
## [1] FALSE
# and nobody with empty rows
unique(dat$id %in% personality_exclusions_2)
## [1] FALSE
# the people who failed attention checks either didn't fill out the diary or the screen time part
unique(dat$id %in% personality_exclusions_3)
## [1] FALSE
# same goes for personality straightliners
unique(dat$id %in% personality_exclusions_4)
## [1] FALSE
## diary
# some people with empty diary entries left, nobody left who didn't participate in the diary (no wonder, we used diary as the base for merging)
# those people will have empty diary entries, but still data for screen time, so no need to exclude them here, they'll be dropped from analysis automatically because of NA
inner_join(diary_exclusions_1, dat %>% select(id, day)) %>% nrow()
## Joining, by = c("id", "day")
## [1] 33
# don't exclude anyone who missed a diary entry
# diary straightliners: need to exclude one person
$id[dat$id %in% diary_exclusions_3] dat
## [1] pp_169 pp_169 pp_169 pp_169 pp_169
## 303 Levels: pp_1 pp_10 pp_100 pp_101 pp_102 pp_103 pp_104 pp_105 pp_106 pp_107 pp_108 pp_109 pp_11 pp_110 pp_111 ... pp_NA
<-
dat %>%
dat filter(!id %in% diary_exclusions_3)
# last, exclude one diary entry that was provided too late (see details above)
<-
dat %>%
dat anti_join(., diary_exclusions_4)
## Joining, by = c("id", "day")
## screen time exclusions
# those with empty rows will have been excluded as we merged diary with totals_long (totals long excluded those who had all NA)
unique(dat$id %in% screen_time_exclusions_1)
## [1] FALSE
Good, then we have our final data set.
Because screen time was filled in retrospectively in the third session, those who didn’t fill in an experience sample will have NA
s on the self-reports, but still a row with data because screen time for that day is there.
So each person has five rows, except for that one participant who filled in one of the surveys too late.
Next, I create an accuracy score for the comparison of objective and subjective phone use indicators. The objective measure is our “true” estimate. We want to know how far off participants were, relative to that true value, in their estimate. For that, we calculate the percentage error by subtracting the objective value from the subjective value (to get difference) and dividing by the objective value (to get error percent). Afterwards, we multiply by 100 to get a percentage. Say I estimated 110 subjective minutes, but the true value (i.e., the objective minutes) is 100. Then the error is 10%, an overestimate. If I estimated 100 subjective minutes, but the true value is 110, the error is ~9%, an underestimate.
In my opinion, that is more intuitive than a difference score.
It’s easier to understand the magnitude of an error in percent (say 80%) than raw units (say 10 minutes).
However, percent error brings one complication with it: If participants estimated 0 social media use, percent error becomes meaningless.
0 - objective / objective will always lead -100%.
There’s 11 cases with an estimate of zero, but actual, objective use.
It’s impossible in this case to determine an error percentage, simply because 0 is meaningless in the formula.
I could use a difference score instead, but that’ll make the interpretation less intuitive.
Those zeros might’ve also been typos, given how rare zeros are in the sample.
I could set those error instances to missing, but in the analysis, we want to be able to compare coefficient predicting both social media and error.
Therefore, I’ll set all three variables to NA
.
<-
dat %>%
dat mutate(
# error social media time
error = (social_media_subjective - social_media_objective) / social_media_objective * 100,
across(
c(social_media_subjective, social_media_objective, error),
~ if_else(error == -100, NA_real_, .x)
) )
I checked their raw data: One participant indicated exactly five hours, but probably meant five minutes (i.e., the participant with an error of 1.49^{4}.
Similarly, the second largest entry seems to be a typo (i.e., 58 minutes).
I’ll set those all entries that are larger than 1500% to NA
.
Also, one participant had zero objective time and zero subjective time.
Dividing by zero to get error above leads to NaN
, so I’ll set that NA
.
<-
dat %>%
dat mutate(
error = if_else(error > 1500, NA_real_, error),
error = if_else(
== 0 & social_media_objective == 0, NA_real_, error
social_media_subjective
) )
Last, some housekeeping, reordering variables and making sure they all have the correct variable type, plus reordering the day
factor.
<-
dat %>%
dat select(
id,:ethnicity,
age
gender,starts_with("duration"),
day,
social_media_subjective,
pickups_subjective,
notifications_subjective,
social_media_objective,
error,
pickups_objective,
weekly_notifications,:relatedness_state,
well_being_state:enjoyable,
low_positive_peaceful:openness,
autonomy_trait:big_five_45
bpns_1%>%
) mutate(
id = droplevels(id),
day = as.factor(day),
day = fct_relevel(
day,"monday",
"tuesday",
"wednesday",
"thursday",
"friday"
) )
When plotting the app data I want them to reflect the final sample, which is why I only keep those participants and surveys in the apps_long
data set that are also in the final data set (i.e., dat
).
I can’t just exclude those participants in apps_long
because I also excluded surveys in diary
on which dat
is based.
Therefore, I only keep those entries in apps_long
which have a corresponding row in dat
(aka entries in both id
and day
).
Also, I’ll remove “week” as a time frame and add the notifications for that app over whole week as a constant per app.
<-
apps_week %>%
apps_long select(
id,
time_frame,
app,
rank,
notifications%>%
) filter(time_frame == "week") %>%
select(-time_frame)
<-
apps_long left_join(
# only those participants and days that are in final data set
%>%
dat select(id, day),
# and the rest of the variables from apps_long, but without week
%>%
apps_long rename(day = time_frame) %>%
filter(day != "week") %>%
select(-notifications),
by = c("id", "day")
%>%
)
# add the notifications for that app per week as a constant
left_join(
.,
apps_week,by = c("id", "app", "rank")
%>%
) select(id, day, rank:notifications) %>%
rename(notifications_per_week = notifications)
Last, there are some NaN
s in the data set after the transformations.
I’ll turn them into missings (i.e., NA
).
<-
dat %>%
dat mutate(
across(
everything(),
~ na_if(.x, "NaN")
) )
Write the analysis file.
write_rds(dat, here("data", "processed_data.rds"))


Vo Nguyen Dang
#Web Developer #Angular #Vue> #Java Spring #Node.js #MySQL #Oracle #MongoDB
#Web Developer #Angular #Vue> #Java Spring #Node.js #MySQL #Oracle #MongoDB
Now, I'm a engineer at M_Service, and a front-end web developer with Angular, Vue and Java.
I always enter and adapt to the new environment quickly. Besides, actively study and update the knowledge related to my career that is one of my strengths. Moreover, I am keen on studying more about state-of-the-art software’s developments including technologies, tools, methods and languages in order to improve my job’ skills. I am constantly evaluating and upgrading my skills so as to stay at the cutting edge of Web/Software’s improvements.
This is the way I build my application...
Requirements Analysis
Development
Quality Assurance
Release and Deployment
MMOMO PAYMENT PLATFORM API AND TOOL ADMIN, M_SERVICE
12/2018 - present
MoMo Payment Platform API is a payment sonlution for business units, allowing customers to use MoMo E-Wallet account to pay for services on various platforms: Desktop Website, Mobile Website, Mobile Application, POS, Pay In Bill, In App MoMo. Tool Admin is a tool support solve unexpected problems without directly interfering with the database.
Team size: 14
Position: Requirement, Coding, Unit Testing
Technologies: Angular, Vue, Java Spring
Kills: Ability to work under high pressure, Teamwork, Time management, Public – speaking, Write.
FIRE WARNING SYSTEM, CANTHO UNIVERSITY
08/2018 – 12/2018
Fire alarm monitoring system for indoor use. Based on temperature, humidity, smoke - gas, infrared sensors. Users use the mobile app and administrator use web.
Team size: 02
Position: Requirement, Design, Coding, Unit Testing
Technologies: React, React native, JavaScript, Thingspeak, Arduino Wifi, Firebase
Kills: Ability to work under high pressure, Teamwork, Time management, Public – speaking, Write.
WEBSITE SHOPPING ONLINE (INTERN PROJECT), ITSOL,.. JSC
06/2018 – 08/2018
Website support online sales.
Team size: 05
Position: Requirement, Design, Coding (Frontend ), Unit Testing
Technologies: Angular 6, HTML, SCSS, JavaScript, Oracle
Kills: Ability to work under high pressure, Teamwork, Time management, Public speaking
WEBSITE SEARCH NUTRITIONAL FOOD, CANTHO UNIVERSITY
01/2018 – 05/2018
The website supports users to search the content, nutrients contained in food (vitamins, minerals), food identity through pictures, calculate the amount of calories provided to the body when choosing the desired food.
Team size: 02
Position: Requirement, Design, Coding, Unit Testing
Technologies: NodeJS, Python, HTML, JavaScript, CSS, MongoDB
Kills: Ability to work under high pressure, Teamwork skills
WEBSITE PROMOTING TOURISM IN VIETNAM, CANTHO UNIVERSITY
01/2018 – 04/2018
Website links travel companies and people who have needs to travel, introduce, promote tourism in Vietnam. Places, services available, support during the travel.
Team size: 05
Position: Requirement, Coding
Technologies: PHP, HTML, CSS, MySQL
Kills: Ability to work under high pressure, Teamwork skills, Communication skills
BUFFER OVERFLOW ACTACK BY FILE PDF & PPSX, CANTHO UNIVERSITY SOFTWARE CENTER
12/2017 – 01/2018
Through the buffer overflow on Microsoft Office and Foxit Reader, system attacks by gathering information, transmitting trojan horse and keyloger steal passwords and tracking victim activity, upgrading to full admin. The right to control the victim computer.
Team size: 02
Position: Requirement, Environmental simulator, Coding
Technologies: ShellScript, Kali Linux, Keyloger, Metasploit Framework Console
Kills: Ability to work under high pressure, Teamwork, Time management, Public – speaking, Write
GAME SUDOKU, CANTHO UNIVERSITY
12/2017 – 01/2018
The application works on Windows operating systems, using the Exhausted search algorithm, using the mouse and virtual keyboard placed in the game, users can select the "hint" function to find the next number to fill. in the box.
Team size: 01
Position: Requirement, Design, Coding & Unit Testing
Technologies: Java, MVC model
Kills: Ability to work under high pressure, English
CANTHO UNIVERSITY
09/2014 - 12/2018
Infomation Technology
CANTHO UNIVERSITY SOFTWARE CENTER
09/2017 - 01/2018
CUSC Certified Ethical Hacker


The principle discovered by Archemides is that a body immersed in fluid will experience an upward force from the surrounding fluid equal to the weight of the fluid it displaces. As applied to a parcel of air, this indicates that a parcel will experience an upward force equal to the difference between the weight of the fluid it displaces and the weight of the parcel, the latter provided by gravity. If the parcel is less dense than the surrounding fluid, it will experience an upward force and will rise. The density of a parcel is related to pressure, temperature, and moisture content through the ideal-gas law, where the dependence on moisture enters through the effect of water vapor on the gas constant. This can be simplified through use of the virtual temperature, defined elsewhere in this module.
As an air parcel is heated by contact with the warm surface, some preferred locations develop temperature above their surroundings at the same pressure and so have lower density. The parcel will rise and, as it reaches levels with lower pressure, will cool from adiabatic expansion as discussed in the preceding tab. If its new density is still lower than the surrounding atmosphere, it will remain buoyant and continue to accelerate until it reaches a level where the density of the environment matches the density of the parcel. Surface heating therefore tends to lead to development of a surface boundary layer where the stratification is determined by adiabatic expansion.
Let's first neglect the effect of water vapor and see how the material in the preceding tabs can be used to predict the rate of change of temperature with altitude, dT/dz. The hydrostatic equation that relates the change in pressure with altitude can be written
and, using the differential form of the Poisson relationship from the previous tab gives ˚C/m or about -10˚C/km. This is the expected lapse rate in the boundary layer just above a heated surface, and it is obtained by combining the ideal-gas law, the Poisson relationship for adiabatic expansion, and the hydrostatic equation relating change in pressure to change in altitude.
If the atmosphere decreases in temperature more slowly than this, the rising parcel will become negatively buoyant and stop rising. Conversely, if the atmosphere decreases in temperature faster than this, the stratification is unstable and it will rapidly overturn to produce the expected lapse rate for adiabatic ascent. It is common to find a surface layer with this lapse rate capped on top by a rising-temperature level or "inversion" that prevents continued ascent of parcels from the surface until it is eroded by continued surface heating and associated increase in the temperature of the surface layer.
It is useful to have a measure of the varying temperature in such a surface layer, and that is provided by the "potential temperature," the temperature that any parcel in the uniformly mixed boundary layer would have if carried adiabatically to the 1000-hPa level. The equation for the potential temperature is . The Poisson relationship from the previous tab shows that the potential temperature remains constant during adiabatic ascent or descent of dry air. This then leads to several alternative representations of buoyancy (defined as the upward acceleration experience by a parcel):
The generalization to moist air is straightforward because the virtual temperature represents the temperature of dry air that would have the same density as the moist parcel, so it is only necessary to replace temperature with virtual temperature or potential temperature with virtual potential temperature.
Here are some questions to test your understanding of buoyancy:
The standard atmosphere uses a reference altitude that is zero at 1013.25 hPa and 15˚C. What is the corresponding potential temperature at the zero reference level?
At a given pressure, density is affected by changes in temperature or in water vapor content. Consider rain falling through a well-mixed surface layer with constant potential temperature. The evaporation of rain cools a parcel, but it also increases the humidity, and these have opposite effects on the density. Which is more important? (I.e., is the density of the parcel higher or lower than before evaporation of rain into it?) [The right information to answer this hasn't been presented, but you have seen the general effect of moisture on density from tab 2 and you have experience with evaporative cooling, so the answer should be evident without backup calculations.]
Right, it becomes higher in density and hence negatively buoyant and begins to sink. How far does it go in a well-mixed layer before stopping? [Although slowed by mixing, it will remain negatively buoyant all the way to the surface. This is an important mechanism leading to downbursts.]
Fast-responding thermometers on aircraft are needed to measure the buoyancy of a parcel. (a) Estimate what response is needed to detect buoyancy below a cloud 1 km in diameter from an aircraft flying at 200 m/s. [small compared to 5 s]. If the precision in measured temperature is 0.3˚C, what is the (approximate) resolution with which buoyancy can be measured? [g*0.3/273=0.01 m/s^2, but the earlier discussion of resolution in module #2 indicated that this should be doubled, so a better answer is 0.02 m/s2. This can still be important: Over 100 s, this acceleration causes a change of 2 m/s, so buoyancy measurements with sufficiently small uncertainty to be used for this purpose are difficult to obtain.]
Once condensation begins in a rising parcel, does that process usually increase or decrease the buoyancy of the parcel? [The processes involved are the release of latent heat, decreasing the density, the reduction of water vapor pressure, increasing the density, and the appearance of liquid water, increasing the density. The first is dominant, so the buoyancy increases, but the third can cause water mass to accumulate to the point where it has a significant effect unless the condensed rain falls out of the parcel.]
In a stable boundary layer (one that resists vertical motion of parcels), does the potential temperature increase, decrease, or remain constant with increasing altitude?


Terence works at Heroku maintaining the Ruby stack and a slew of OSS projects such as Bundler and Resque, as well as helping with the Rails Girls movement. When he's not going to an awesome Heroku or Ruby event, he lives in Austin, TX, the taco capital of America.
(Terence loves Friday hugs, EVERY DAY OF THE WEEK!  On October 17, 2012, rubygems.org went down. A Dependency API was built to be used by Bundler 1.1+ to speed up `bundle install`. Unfortunately, it was a bit too popular and the service caused too much load on the current infrasture. In order to get rubygems.org back up the API had to be disabled. You can watch the post-mortem, http://youtu.be/z73uiWKdJhw, for details.
Members in the community stepped up and built a compatible Dependency API service called the Bundler API. Working with the rubygems.org team, we were able to bring the API up for everyone within a week. In this talk, I will cover the process we went through of extracting the API out into a separate Sinatra app that now runs on Heroku. I'll go over how the API works and how Bundler itself uses it. Since we don't have direct access to their database, we needed to build a syncing service to keep our local cache up to date. We'll discuss the original sequential implementation of the sync code and how we improved performance through the use of a consumer thread pool. The sync time down was cut from 16 mins to 2-3 mins. Next, we'll talk about the productization steps we took for visibility to make sure the app is performing well.
We're prototyping a replay service, to replay production traffic to different Heroku apps. With this we can compare the performance between the current MRI app in production and the same app running on JRuby. This will also allow us to test any changes/features against real production load. We'll go over how to set this up.


The language and its implementation are described in [Griswold1971] and [Griswold1972].
For command line options see snobol4cmd(1).
Extensions from Catspaw SNOBOL4+, SPITBOL and SITBOL have been added, see snobol4ext(1).
Includes BLOCKS (SNOBOL4B) extensions, see snobol4blocks(1).
On ASCII-based systems, any character with the 8th bit set is treated as “alphabetic”, and can start, or be used in identifiers and labels. This includes characters from the “upper half” of national character sets and all bytes resulting from the UTF-8 encoding of Unicode characters. Include file utf.sno implements pattern matching functions for UTF-8 sequences.
Programs may be entered in mixed case; By default lower case identifiers are folded to upper case (see &CASE and –CASE). Case folding is performed by using the C library islower(3) test, and then using toupper(3) to convert the lower-case characters to upper case. When using UTF-8 encoded characters in code, case folding should be disabled, to prevent any bytes which appear to be lower case in the current locale from being modified.
The following operator character sequences are permitted and represent a cross between PDP-10 Macro SNOBOL, SITBOL and Catspaw SPITBOL usage:
| Assignment: | = _ |
| Comment line: | * # | ; ! |
| Continuation line: | + . |
Both square brackets ([]) and angle brackets (<>) may be used to subscript arrays and tables. The TAB (ASCII 9) character is accepted as whitespace.
Underscore (_) and period (.) are legal within identifiers and labels.
Note that the use of the pound sign for comments allows use of the script interpreter (hash-bang) sequence at the top of a file marked as executable: “#!/usr/local/bin/snobol4” or “#!/usr/bin/env snobol4”
See snobol4op(1) for operators.
1. The current working directory (“.”).
2. Any directories specified on the command line using -I options, in the order specified.
3a. Directories from the the SNOPATH environment variable (see below), if defined.
3b. If SNOPATH is not defined, the SNOLIB environment variable (or a compiled in default) is used as base to add the following directories:
The LOAD() function will also check for the file in shared subdirectory in each directory in the search path.
| sdb(1) | SNOBOL4 Debugger |
| snobol4cmd(1) | command line options |
| snobol4ctrl(1) | control lines |
| snobol4error(1) | &ERRTYPE and &ERRTEXT values |
| snobol4ext(1) | extensions to BTL SNOBOL4 |
| snobol4func(1) | built-in function list |
| snobol4io(1) | input/output |
| snobol4key(1) | keywords |
| snobol4op(1) | operators |
| snobol4blocks(1) | SNOBOL4B BLOCKS extension |
| snopea(1) | convert snopea documentation to roff and HTML |
| snobol4dirs(3) | directory access functions |
| snobol4ezio(3) | easy to use file I/O |
| snobol4ffi(3) | Foreign Function Interface functions |
| snobol4fork(3) | subprocess interface functions |
| snobol4host(3) | HOST and O/S functions |
| snobol4logic(3) | bit logic & formatting functions |
| snobol4ndbm(3) | keyed file access functions |
| snobol4random(3) | pseudo-random numbers functions |
| snobol4readline(3) | input with line editing |
| snobol4setup(3) | loadable module builder |
| snobol4sprintf(3) | formatting function |
| snobol4sqlite3(3) | SQLite database interface functions |
| snobol4sqlite3dbm(3) | DBM interface using SQLite |
| snobol4stat(3) | file metadata functions |
| snobol4stcl(3) | Tcl/Tk interface functions |
| snobol4time(3) | date/time functions |
| snolib(3) | misc library functions |
| snopea(7) | A little “Plain Old Documentation” format for SNOBOL4 |
Philip. L. Budne (CSNOBOL4)
Mark Emmer (code from SNOBOL4+)
Viktors Berstis (code from Minnesota SNOBOL4)
James F. Gimpel (SNOBOL4B)
I/O retains some record oriented flavor (maximum line length on input).
“Dynamic” storage cannot be expanded after startup.
Integer math can never fail, even on overflow.
Oversize integer constants may not be detected.


Early Versions (26/7/2020 -> TbA)
The Start (26/7/2020)
Created and started the project.
v0.1 ~ The First
Version (29/7/2020)
The first officially released version of the game.
Content:
- Implemented Multipliers.
-
Started work on 3 tabs, but only the 1st tab has content
for now. They are:
- Multipliers
- Settings
- Statistics
- Implemented Notations, but only Scientific Notation is supported.
- Simple CSS.
- Added Multiplier Prestiges.
-
Production is based on time since last frame to stabilise progress and
to allow for off-tab progression.
No Offline Progression yet
though.
-
Added and started working on the Change Log on this game, which is
what you are on currently.
- And Useless Functions!
v0.2 ~ A Crucial Update (1/8/2020)
An important update that greatly increases playability, but isn't too
major content-wise.
Content:
-
Added an Auto-saving feature. Austosaves every second. This also allows for more
progressing means like offline-like progression.
-
Balanced the game.
-
Decreased the Multiplier Prestige costs from
[250, 1000, 5e4, 1e7, 1e10, 1e15, 1e20, 1e26, 1e32]
to
[250, 1000, 5e4, 7.5e6, 1e10, 1.25e14, 1e19, 2e24, 1e30]
.
-
Also nerfed the effect from Multiplier Prestiges to Number growth,
from
((x + 1)2 + x + 1) / 2 to
simply x+1, where x represents
how many Multiplier Prestiges you have performed.
-
Optimised the game's code a bit by decreasing lines of code and
processes (such as
for
loops) while maintaining performance.
- Some CSS tweaks to make things look a lil' better.
p
-
Tweaked + sorted out some JS code and changed the
game.multipliers
format from
{amount:[number,number],boost:[number,number]}
to
[{amount:number,boost:number},{amount:number,boost:number}]
, and changed the code that gets the variable accordingly.
-
Removed the effect from some browsers on mobile where when you double
click, the screen will zoom in, and the click delay. This gets
annoying, so I decided to remove that feature.
- Also disabled selecting. This may be a controversial change.
- Note: On iOS Safari, double tapping to zoom in can still happen.
- Added more styling to the Change Log.
-
Also added PC support! I did this by performing as listed in
the Bug Fixes section of this Update.
Bug Fixes:
-
Fixed the "Buy Multiplier" Bug (both on Mobile and PC).
This bug originated in v0.1, the first version of this game.
The game was not playable on most PCs, as the "Buy Multiplier"
buttons fail to work.
On Mobile, the bug is not as major. Only sometimes do "Buy Multiplier" buttons work.
I fixed this bug by:
-
Changing the way the Multipliers section of the 1st
tab, or "tab1" in the HTML, updates.
In this way, no longer would it update every frame, rather only
when the player performs a certain action such as buying a
Multiplier.
-
Also separating the code that updates the Multiplier values from
initially, in order to make this possible.
v0.21 ~ The Save Transferring Update (4/8/2020)
A medium update that adds more options for saving.
Content:
- Added 2 buttons in the Settings tab - Importing and Exporting.
- Made it so that when you click "Import", there will be a custom prompt, because if a normal prompt is executed, the game will pause, losing production.
- Export - Exports a save in not Base 64 (secret!),
unlike other incrementals exporting in Base 64 (
btoa()
function) - which is generic.
- Also added the option to reset your save. .-.
- Tweaked the code in the
Notations.js
file, so that numbers greater than 1 million is to be displayed in scientific notation.
- Tiny CSS changes.
- Finally, sorted out the code in the Save Handling System.
Bug Fixes:
Known Bugs:
v0.3 ~ A Prestige Layer (7/9/2020)
The update that adds the first ever Prestige Layer, and improvises many features. Also a rename of the game took place. This update took forever for whatever reason.
school
Content:
- Renamed Multiplying Idle Game to IncreMultiplication, and thus relocated the URL from https://idlesquadron.github.io/multiplying-idle-game/. It sounds more original that way xd.
- Initialised the first Prestige Layer; Products.
- This allows for continued game content after a Number of 1.000e50.
- Added its currency - Factored Points. Once you reach 1.000e50, you can start earning it. The more the Number, the more the FP gain.
- Spend FP on Factor Upgrades, which boost various sources.
- New QoL feature - Max All Multipliers. Unlocks at Product.
- Overhauled the concept of Multipliers with the Multiplier Milestones feature.
- It's a global value that holds 2 values - the boost and rate. The starting values are 2 and 10, respectively.
- Multiplier Milestones boost a Multiplier by boostx every rate of the respective Multiplier (stacks multiplicatively). It can generally be represented by this formula, boost floor(multAmount/rate). It applies to every Multiplier.
- Added current Multiplier Milestone boost to a Multiplier to each of the Multipliers, to the right of their Amount counter.
- Regarding and as a result for the above feature, the (base) Multiplier cost scalings have been buffed. From
10round((m + 1) ÷ 2 + 1) × floor((m + 1) ÷ 2 + 1) ×
(log10((m + 2)1.3 × 2) + 1)1.05a1.01 × 5 - 5, it is now
10round((m + 1) ÷ 2 + 1) × floor((m + 1) ÷ 2 + 1) ×
(sqrt(m + 3) + 1)1.05a1.01 × 5 - 5, where m represents the number Multiplier and a represents mth Multiplier amount.
- Added more settings!
- 5 more notations are now implemented - Engineering, Standard, Logarithmic, Alphabetic and Long Alphabetic, along with its Notation button to cycle through them. Scientific is default.
- Along with Notations, any value display will change according to your notation.
- Along with this is customisation of the Growth notation, either additively or multiplicatively.
- If the Notation is set to Logarithmic with Growths at Multiplicative, the growth will determine how much the logarithm (in e5.839, 5.839 is the logarithm) grows per second.
- You can now manipulate the Tick Interval of the game, meaning the interval at where the game 'updates', or loops.
- Added simple statistics, with 3 subtabs (the Achievements subtab isn't implemented yet). These are mostly just simple milestones involving totals, including Number and time, such as time since start, last Multiplier Prestige and last Product. There is also a Time Record for Product.
- This also results in an addition of notation for time.
- Made CSS more dynamic, with
:hover
and more. Also a few tweaks.
- The top Number and tabs are now
position: sticky
, meaning that it will follow your scroll position as soon as you start scrolling down and when it would go off-screen.
- Made the Multipliers less spaced apart.
- Made the internal JS code a bit better.
- The
game
variable now stores a lot more information.
- Also I sorted out the
game
variable, with time data being in game.time
(game.lastTick
is now game.time.lastTick
).
- Added more explanations in the code via comments (
//
or /* */
).
- As a result of the inclusion of the Refresh Rate setting, the way the game is updated is changed. It no longer uses a
setInterval()
, now it uses a self-invoking looping setTimeout()
function. This was done as a looping setTimeout()
is a lot more flexible with changing intervals.
- I also did this for the Auto-Saving loop.
- Tried to make the code more readable and accessible.
- Also made a few more shortcut conventions (in js/Shortcuts.js).
- And more Formulas!
Bug Fixes:
- Fixed a small rounding error in Scientific notation.
This bug originated in v0.1.
- Instances of where this happens is a number like 9,999,999,989 getting notated to 10.000e9 where it should be 9.999e9 or 1.000e10.
v0.301 ~ The 1st smol Update (9/9/2020)
A very small update which fixes only one bug.
Content:
Bug Fixes:
- Fixed a bug where FU21 becomes exceedingly more powerful than stated.
This is caused by part of FU21's formula being Date.now() - game.time.since.start
, but game.time.since.start
is not a timestamp of Date.now()
, rather a counter in ms that goes up.
More updates coming soon. They will be listed here as soon as possible...


Google OTP Key Setting
OTP key is ...
Move mouse pointer over here
Confirm
Cancel
Donglein Key Setting
Connect USB ...
USB
Connect USB ...
Donglein Key
Set donglein key to MBR ...
Complete
Remove USB ...
Next
Confirm
Cancel
Smart Auth
Auth State
Auth List Modification
Settings
Current Auth List
Normal Windows Password
Always required
Current Settings
Off
Hide other users' logon tiles
Prohibit fallback credential provider
Current Auth List
Normal Windows Password
Always required
Available Auth List
On / Off
Hide other users' logon tiles (Recommended)
Prohibit fallback credential provider (Recommended)


You are using a very old browser.
You are seeing this page because we detected that you are using a very old and unsupported browser. Your browser does not support major security features that are essential for a safer web.
We highly recommend you to update your browser.
If you believe you have arrived here in error, please contact us!


Forgot Password ?
Sign up and discover great amount of new opportunities!
If you already has an account, just sign in. We've missed you!


| Modifier and Type | Interface and Description |
|---|---|
interface |
JobContext |
| Modifier and Type | Method and Description |
|---|---|
void |
OutputCommitter.abortJob(JobContext context,
JobStatus.State runState)
This method implements the new interface by calling the old method.
|
void |
OutputCommitter.cleanupJob(JobContext context)
|
void |
OutputCommitter.commitJob(JobContext context)
This method implements the new interface by calling the old method.
|
boolean |
OutputCommitter.isCommitJobRepeatable(JobContext jobContext) |
boolean |
OutputCommitter.isRecoverySupported(JobContext context)
This method implements the new interface by calling the old method.
|
void |
OutputCommitter.setupJob(JobContext jobContext)
This method implements the new interface by calling the old method.
|
| Modifier and Type | Method and Description |
|---|---|
protected boolean |
CombineFileInputFormat.isSplitable(JobContext context,
org.apache.hadoop.fs.Path file)
Subclasses should avoid overriding this method and should instead only
override
CombineFileInputFormat.isSplitable(FileSystem, Path) . |
| Modifier and Type | Interface and Description |
|---|---|
interface |
MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
The context that is given to the
Mapper . |
interface |
ReduceContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
The context passed to the
Reducer . |
interface |
TaskAttemptContext
The context for task attempts.
|
interface |
TaskInputOutputContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
A context object that allows input and output from the task.
|
| Modifier and Type | Class and Description |
|---|---|
class |
Job
The job submitter's view of the Job.
|
class |
Mapper.Context
The
Context passed on to the Mapper implementations. |
class |
Reducer.Context
The
Context passed on to the Reducer implementations. |
| Modifier and Type | Method and Description |
|---|---|
static JobContext |
ContextFactory.cloneContext(JobContext original,
org.apache.hadoop.conf.Configuration conf)
Clone a
JobContext or TaskAttemptContext with a
new configuration. |
| Modifier and Type | Method and Description |
|---|---|
void |
OutputCommitter.abortJob(JobContext jobContext,
JobStatus.State state)
For aborting an unsuccessful job's output.
|
abstract void |
OutputFormat.checkOutputSpecs(JobContext context)
Check for validity of the output-specification for the job.
|
void |
OutputCommitter.cleanupJob(JobContext jobContext)
Deprecated.
|
static JobContext |
ContextFactory.cloneContext(JobContext original,
org.apache.hadoop.conf.Configuration conf)
Clone a
JobContext or TaskAttemptContext with a
new configuration. |
void |
OutputCommitter.commitJob(JobContext jobContext)
For committing job's output after successful job completion.
|
abstract List<InputSplit> |
InputFormat.getSplits(JobContext context)
Logically split the set of input files for the job.
|
boolean |
OutputCommitter.isCommitJobRepeatable(JobContext jobContext)
Returns true if an in-progress job commit can be retried.
|
boolean |
OutputCommitter.isRecoverySupported(JobContext jobContext)
Is task output recovery supported for restarting jobs?
If task output recovery is supported, job restart can be done more
efficiently.
|
abstract void |
OutputCommitter.setupJob(JobContext jobContext)
For the framework to setup the job output during initialization.
|
| Modifier and Type | Method and Description |
|---|---|
void |
DBOutputFormat.checkOutputSpecs(JobContext context) |
List<InputSplit> |
DataDrivenDBInputFormat.getSplits(JobContext job)
Logically split the set of input files for the job.
|
List<InputSplit> |
DBInputFormat.getSplits(JobContext job)
Logically split the set of input files for the job.
|
| Modifier and Type | Method and Description |
|---|---|
static boolean |
FileInputFormat.getInputDirRecursive(JobContext job) |
static org.apache.hadoop.fs.PathFilter |
FileInputFormat.getInputPathFilter(JobContext context)
Get a PathFilter instance of the filter set for the input paths.
|
static org.apache.hadoop.fs.Path[] |
FileInputFormat.getInputPaths(JobContext context)
Get the list of input
Path s for the map-reduce job. |
static long |
FileInputFormat.getMaxSplitSize(JobContext context)
Get the maximum split size.
|
static long |
FileInputFormat.getMinSplitSize(JobContext job)
Get the minimum split size
|
static int |
NLineInputFormat.getNumLinesPerSplit(JobContext job)
Get the number of lines per split
|
List<InputSplit> |
CombineFileInputFormat.getSplits(JobContext job) |
List<InputSplit> |
NLineInputFormat.getSplits(JobContext job)
Logically splits the set of input files for the job, splits N lines
of the input as one split.
|
List<InputSplit> |
FileInputFormat.getSplits(JobContext job)
Generate the list of files and make them into FileSplits.
|
List<InputSplit> |
DelegatingInputFormat.getSplits(JobContext job) |
protected boolean |
CombineFileInputFormat.isSplitable(JobContext context,
org.apache.hadoop.fs.Path file) |
protected boolean |
TextInputFormat.isSplitable(JobContext context,
org.apache.hadoop.fs.Path file) |
protected boolean |
KeyValueTextInputFormat.isSplitable(JobContext context,
org.apache.hadoop.fs.Path file) |
protected boolean |
FixedLengthInputFormat.isSplitable(JobContext context,
org.apache.hadoop.fs.Path file) |
protected boolean |
FileInputFormat.isSplitable(JobContext context,
org.apache.hadoop.fs.Path filename)
Is the given filename splittable? Usually, true, but if the file is
stream compressed, it will not be.
|
protected List<org.apache.hadoop.fs.FileStatus> |
FileInputFormat.listStatus(JobContext job)
List input directories.
|
protected List<org.apache.hadoop.fs.FileStatus> |
SequenceFileInputFormat.listStatus(JobContext job) |
| Modifier and Type | Method and Description |
|---|---|
List<InputSplit> |
CompositeInputFormat.getSplits(JobContext job)
Build a CompositeInputSplit from the child InputFormats by assigning the
ith split from each child to the ith composite split.
|
| Modifier and Type | Class and Description |
|---|---|
class |
WrappedMapper.Context |
| Modifier and Type | Method and Description |
|---|---|
static <K1,V1,K2,V2> |
MultithreadedMapper.getMapperClass(JobContext job)
Get the application's mapper class.
|
static int |
MultithreadedMapper.getNumberOfThreads(JobContext job)
The number of threads in the thread pool that will run the map function.
|
| Modifier and Type | Method and Description |
|---|---|
void |
BindingPathOutputCommitter.abortJob(JobContext jobContext,
JobStatus.State state) |
void |
FileOutputCommitter.abortJob(JobContext context,
JobStatus.State state)
Delete the temporary directory, including all of the work directories.
|
void |
SequenceFileAsBinaryOutputFormat.checkOutputSpecs(JobContext job) |
void |
LazyOutputFormat.checkOutputSpecs(JobContext context) |
void |
FileOutputFormat.checkOutputSpecs(JobContext job) |
void |
FilterOutputFormat.checkOutputSpecs(JobContext context) |
void |
NullOutputFormat.checkOutputSpecs(JobContext context) |
void |
BindingPathOutputCommitter.cleanupJob(JobContext jobContext) |
void |
FileOutputCommitter.cleanupJob(JobContext context)
Deprecated.
|
void |
BindingPathOutputCommitter.commitJob(JobContext jobContext) |
void |
FileOutputCommitter.commitJob(JobContext context)
The job has completed, so do works in commitJobInternal().
|
protected void |
FileOutputCommitter.commitJobInternal(JobContext context)
The job has completed, so do following commit job, include:
Move all committed tasks to the final output dir (algorithm 1 only).
|
static boolean |
FileOutputFormat.getCompressOutput(JobContext job)
Is the job output compressed?
|
static boolean |
MultipleOutputs.getCountersEnabled(JobContext job)
Returns if the counters for the named outputs are enabled or not.
|
org.apache.hadoop.fs.Path |
FileOutputCommitter.getJobAttemptPath(JobContext context)
Compute the path where the output of a given job attempt will be placed.
|
static org.apache.hadoop.fs.Path |
FileOutputCommitter.getJobAttemptPath(JobContext context,
org.apache.hadoop.fs.Path out)
Compute the path where the output of a given job attempt will be placed.
|
static org.apache.hadoop.io.SequenceFile.CompressionType |
SequenceFileOutputFormat.getOutputCompressionType(JobContext job)
Get the
SequenceFile.CompressionType for the output SequenceFile . |
static Class<? extends org.apache.hadoop.io.compress.CompressionCodec> |
FileOutputFormat.getOutputCompressorClass(JobContext job,
Class<? extends org.apache.hadoop.io.compress.CompressionCodec> defaultValue)
Get the
CompressionCodec for compressing the job outputs. |
protected static String |
FileOutputFormat.getOutputName(JobContext job)
Get the base output name for the output file.
|
static org.apache.hadoop.fs.Path |
FileOutputFormat.getOutputPath(JobContext job)
Get the
Path to the output directory for the map-reduce job. |
static Class<? extends org.apache.hadoop.io.WritableComparable> |
SequenceFileAsBinaryOutputFormat.getSequenceFileOutputKeyClass(JobContext job)
Get the key class for the
SequenceFile |
static Class<? extends org.apache.hadoop.io.Writable> |
SequenceFileAsBinaryOutputFormat.getSequenceFileOutputValueClass(JobContext job)
Get the value class for the
SequenceFile |
boolean |
BindingPathOutputCommitter.isCommitJobRepeatable(JobContext jobContext) |
boolean |
FileOutputCommitter.isCommitJobRepeatable(JobContext context) |
boolean |
BindingPathOutputCommitter.isRecoverySupported(JobContext jobContext) |
protected static void |
FileOutputFormat.setOutputName(JobContext job,
String name)
Set the base output name for output file to be created.
|
void |
BindingPathOutputCommitter.setupJob(JobContext jobContext) |
void |
FileOutputCommitter.setupJob(JobContext context)
Create the temporary directory that is the root of all of the task
work directories.
|
| Constructor and Description |
|---|
FileOutputCommitter(org.apache.hadoop.fs.Path outputPath,
JobContext context)
Create a file output committer
|
PartialFileOutputCommitter(org.apache.hadoop.fs.Path outputPath,
JobContext context) |
PathOutputCommitter(org.apache.hadoop.fs.Path outputPath,
JobContext context)
Constructor for a job attempt.
|
| Modifier and Type | Method and Description |
|---|---|
static String |
KeyFieldBasedComparator.getKeyFieldComparatorOption(JobContext job)
Get the
KeyFieldBasedComparator options |
String |
KeyFieldBasedPartitioner.getKeyFieldPartitionerOption(JobContext job)
Get the
KeyFieldBasedPartitioner options |
| Modifier and Type | Class and Description |
|---|---|
class |
WrappedReducer.Context |
| Modifier and Type | Class and Description |
|---|---|
class |
JobContextImpl
A read-only view of the job that is provided to the tasks while they
are running.
|
class |
MapContextImpl<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
The context that is given to the
Mapper . |
class |
ReduceContextImpl<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
The context passed to the
Reducer . |
class |
TaskAttemptContextImpl
The context for task attempts.
|
class |
TaskInputOutputContextImpl<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
A context object that allows input and output from the task.
|
Copyright © 2008–2022 Apache Software Foundation. All rights reserved.


Main Menu
View Your Energy Certificate
View Qualified Routes on A Map
View Daily Trip Summary
Personal Data Management
Sign Out


IM TECHNOLOGIES
A Major part of InspiredMemories which serves technology to the world of untouchability. Dive in to the depth of our products & Services which can make your mind to move towards blue. We welcome you to our world of inspirational makeovers.


| # | Optimal Cluster Count | Created | Global Si | Global Cluster Si | Minimum Cluster Count | Maximum Cluster Count | Iterations Per Cluster | Maximum Optimization Count | Total Calculation Time | Status | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| {{clusterCalculation.id}} | {{clusterCalculation.clusterCount}} | {{clusterCalculation.created | date:'medium' }} | {{clusterCalculation.globalSi}} | {{clusterCalculation.clusterSi}} | {{clusterCalculation.minimumClusterCount}} | {{clusterCalculation.maximumClusterCount}} | {{clusterCalculation.iterationsPerCluster}} | {{clusterCalculation.maximumOptimizationsCount}} | {{clusterCalculation.totalCalculationTimeString}} | New Clustering Completed Failed | View Results |


Libraries
Folder: [ROOT]/code/package
- [ROOT]/code/package/_lib
- [ROOT]/code/package/_vendor
- [ROOT]/code/package/loader.php is a lead loader.
-
you need define('_LOAD_VENDOR', true); to enabled vendor directory (by default, it's disable for performance)
Library is the place you put your generic library or third party libraries


sbart: Sequential BART for Imputation of Missing Covariates
Implements the sequential BART (Bayesian Additive
Regression Trees) approach to impute the missing covariates. The
algorithm applies a Bayesian nonparametric approach on factored
sets of sequential conditionals of the joint distribution of the
covariates and the missingness and applying the Bayesian additive
regression trees to model each of these univariate
conditionals. Each conditional distribution is then sampled using
MCMC algorithm. The published journal can be found at
<https://doi.org/10.1093/biostatistics/kxw009> Package provides a
function, seqBART(), which computes and returns the imputed
values.
Downloads:
Reverse dependencies:
Linking:
Please use the canonical form
https://CRAN.R-project.org/package=sbart
to link to this page.


| Michelle |
harerimana |
Rwanda |
<EMAIL_ADDRESS>|
young mentor |
5 years |
I was sent my detail your email account admin |
|
|
| claude |
John |
UGANDA |
<EMAIL_ADDRESS>|
family care |
10 years |
I was sent my detail your email account admin |
|
|
| Elisabeth |
nkurunziza |
BURUNDI |
<EMAIL_ADDRESS>|
Vice minister of youth |
3 years |
I was sent my detail your email account admin | |
|
| Eric |
pierre celestin |
DRC |
<EMAIL_ADDRESS>|
minister of familly and youth |
10 years |
I was sent my detail your email account admin |
|
|
| Laissa |
Teddy |
Tanzania |
<EMAIL_ADDRESS>|
youth connection mentors |
3 years |
I was sent my detail your email account admin |
|
|
| Bugingo |
moussa |
Ghana |
<EMAIL_ADDRESS>|
teacher |
15 years |
I was sent my detail your email account admin |
|
|
| Lydia |
Nicole |
Gambia |
<EMAIL_ADDRESS>|
pastor |
9 years |
I was sent my detail your email account admin |
|
|
| Emmanuel |
nicholas |
France |
<EMAIL_ADDRESS>|
programmer |
4 years |
I was sent my detail your email account admin |
|
|
| Emerance |
mouhamed |
Egypt |
<EMAIL_ADDRESS>|
islam woman foundation |
4 years |
I was sent my detail your email account admin |
|
|
| Mbaraga |
Rwema innocent |
britaine |
<EMAIL_ADDRESS>|
panafricanist |
7years |
I was sent my detail your email account admin |
|
|


Cacti (T. peruvianus), Cacti (T. pachanoi) & Cannabis
I had tried San Pedro twice before, once by eating a bowlful of fresh chunks and once by blending it with orange juice into a pulpy, foamy concoction. Both tasted hideous, and the results were unimpressive at best (I didn’t even get sick). Though years passed without any inclination on my part to do it again, I was inspired to give it another shot after finding four little Pedros in the garden section of Lowes.
This particular story begins with my good friend K and I processing about 728g of Peruvianus and 784g of Pachanoi I had received in the mail. We started by removing the spines and freezing the vegetables for a few days. Then we wrapped them in foil and briefly ran hot water over them to quick-thaw the outer layer and loosen the skin, which all peeled away very nicely. The green tissue was then separated and processed via blender into a guacamolish substance, which was added to the mucilage that we wrung from the rest of the cacti, and strained several times through cheesecloth until we were left with what looked like cloudy lime-green honey. All in all, this yielded about 3.75 cups, which we divided equally between the two of us.
We did this in my apartment, which is where we normally do this kind of thing. Pleasant associations a-plenty here. Though I was keeping my hopes high and my expectations low, I was excited simply by my friend’s excitement at trying something new.
Because I have the metabolism of a hummingbird, K went an hour before me so that the timing of our trips would coincide better (a trick we learned with X). He drank his slime down at a slow, reasonable pace that took maybe twenty minutes to finish. Though it was not quite as awful as I had led him to expect, he was grateful for the grapefruit juice chaser nonetheless.
 Though I was less than eager to imbibe the cold green goo, I was able to force down all but the dregs in four chugs. It took a little fortitude to pull this off, but the Pedro preparations I had employed before had tasted much worse and felt awful going down.
By this time, K was exhibiting marked physical arousal, wandering around my living room to fend off nausea while twirling a sizable carven stick in his hands. His pupils were dilated, but aside from a feeling of physical malaise and a sense of mild alteration, he reported no other effects.
We conversed freely for about an hour, mostly trying to kill time until the drug kicked in. Then the nausea began creeping up my throat, and I retreated to the bathroom whereupon I vomited up some liquid and immediately felt better. I took my sickness as a good sign that something was happening. I came out, was momentarily startled by the reflection of light off of my guitar, and realized that I too was feeling mildly altered.
 I felt good, but nothing particularly special was happening. Three hours had passed since my friend ingested the green honey, and two for me, so I decided to try to take things up a notch by smoking what K affectionately calls “the sweet ganj.”
After about 1.5 little bowls between the two of us, things began to accelerate.
“Uh oh,” K said, having closed his eyes. “I’m getting colors and seeing deals.” I too had closed my eyes and was also was seeing colors and deals, in the form of what looked like a batik of a turtle’s shell streaming with purples and reds. I retired to the floor and gave K the couch, the better for him to see the lightshow.
“What does this mean to you?” He asked me: “Crouching Color, Hidden Skwirkle.”
“I don’t know,” I said. “A color crouching behind a bush, stalking something?”
“Yes!” He said. “A color stalking a skwirkle that’s trying to hide. It’s like the colors are chasing the skwirkles.”
Skwirkle. K was in neologism territory now, a good indicator of things to come.
I set my head on a large pillow and pulled another up over my face, and remained in this position for a good long while, feeling a decent body high (more intense than the sweet ganj by itself, but not as pronounced as with shrooms or X) as more designs continued to project themselves against my psychic widescreen. Most of them were so ephemeral and in such extreme flux that I could not, and cannot, describe in any more detail beyond that they appeared as very unusual geometrical forms overlaid atop each other, coursing and rippling with colors of contrasting brightness to complement my flight of ideas. I can also remember seeing hundreds of thousands of arrowheads floating in space, maintaining a spherical pattern that would shrink and grow as the arrowheads put more or less distance between each other. This theme gave rise to an idea/vision of some kind of divine, space-faring stellar bow. The fuck?
K notified me that he was now able to perceive the spirit world. “I can see why the cactus is used spiritually,” he said. Turns out he could squint so the candle flames would appear to stream up and down, which served as a substrate for another hallucination, which would then generate another hallucination perceived in three dimensions. K, engrossed by the actions of a spirit-arm reaching for him, coined this phenomenon meta-hallucination and said the mescaline + MJ experience was proving to be more visually powerful for him than our mushroom or ayahuasca experiments.
I asked K if he felt like braving the outside world, and he was up for it. We went for a walk around my complex, openly staring at wispy silver clouds racing against the night sky, and communicating in an amusing mixture of esoteric humor and fluent conversational nonsense, trying not to arouse attention while stumbling up the street and spinning in circles with paranoia-tinted excitement. It would have been *really* cool to go into the woods, but it had rained a lot recently and I had had enough slime for one night without getting more in my sandals. (Sorry, K.)
When we got back to my place, I produced a calumet and we fired up more of the sweet ganj. We did this several more times over the next eight hours or so, retreating into blissful inner or spiritual worlds as our visions and flight of ideas intensified before emerging once again into the milder consensual insanity we call folie a deux.
Around 8 A.M., K was still feeling too silly to drive home, so he crashed and we slept into the wee hours of the afternoon. I woke up feeling very slightly hungover, with a pronounced headache.
To sum up this experience, I would have to say that Pedro was less than I was really hoping for, but certainly more than I was expecting based on earlier trials. Unlike with mushrooms, however, I don’t feel as if any lessons of eternal value were imparted. I also think the mental clarity pervading the experience contributed to the perceived mildness of the drug, though the copious amount of sweet ganj we smoked throughout the night helped the trip along tremendously. The sloppy calculations I had performed beforehand, based on average potencies and total wet weight, had come out to a little over 400mg of mescaline for each of us. I don’t think we ended up taking that much, either because the potencies of our cacti were below the mean and/or our extraction process was inefficient, but it nonetheless provided for a worthwhile and delightful evening that’s definitely worth repeating.
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.


/*
Copyright 2017 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const assert = require('assert');
const fse = require('fs-extra');
const path = require('path');
const defaults = require('./options/defaults');
const errors = require('../lib/errors');
const getFileManifestEntries = require('../lib/get-file-manifest-entries');
const injectManifestSchema = require('./options/inject-manifest-schema');
const validate = require('./options/validate');
/**
* This method creates a list of URLs to precache, referred to as a "precache
* manifest", based on the options you provide.
*
* The manifest is injected into the `swSrc` file, and the regular expression
* `injectionPointRegexp` determines where in the file the manifest should go.
*
* The final service worker file, with the manifest injected, is written to
* disk at `swDest`.
*
* @param {module:workbox-build.Configuration} config
* @return {Promise<{count: Number, size: Number}>} A promise that resolves once
* the service worker file has been written to `swDest`. The `size` property
* contains the aggregate size of all the precached entries, in bytes, and the
* `count` property contains the total number of precached entries.
*
* @memberof module:workbox-build
*/
async function injectManifest(config) {
const options = validate(config, injectManifestSchema);
if (path.normalize(config.swSrc) === path.normalize(config.swDest)) {
throw new Error(errors['same-src-and-dest']);
}
const globalRegexp = new RegExp(options.injectionPointRegexp, 'g');
const {count, size, manifestEntries} = await getFileManifestEntries(options);
let swFileContents;
try {
swFileContents = await fse.readFile(config.swSrc, 'utf8');
} catch (error) {
throw new Error(`${errors['invalid-sw-src']} ${error.message}`);
}
const injectionResults = swFileContents.match(globalRegexp);
assert(injectionResults, errors['injection-point-not-found'] +
// Customize the error message when this happens:
// - If the default RegExp is used, then include the expected string that
// matches as a hint to the developer.
// - If a custom RegExp is used, then just include the raw RegExp.
(options.injectionPointRegexp === defaults.injectionPointRegexp ?
'workbox.precaching.precacheAndRoute([])' :
options.injectionPointRegexp));
assert(injectionResults.length === 1, errors['multiple-injection-points'] +
` ${options.injectionPointRegexp}`);
const entriesString = JSON.stringify(manifestEntries, null, 2);
swFileContents = swFileContents.replace(globalRegexp, `$1${entriesString}$2`);
try {
await fse.mkdirp(path.dirname(options.swDest));
} catch (error) {
throw new Error(errors['unable-to-make-injection-directory'] +
` '${error.message}'`);
}
await fse.writeFile(config.swDest, swFileContents);
return {count, size};
}
module.exports = injectManifest;


Just finished my tutorial for comparative methods on continuous traits in R, which I’ll be presenting on Wednesday with Justen Whittall. The tutorial is up on the Bodega Phylogenetics Wiki, together with the necessary data files.
Errors that shouldn’t happen: a few package bugs in simulation functions
Assembling the tutorial exposed a few more frustrations in the R packages. Consider simulating OU with rTraitCont:
## Load the libraries, simulate a tree
require(geiger)
require(TreeSim)
tree <- sim.bd.taxa(100,1,1,0)[[1]]
## This is OK
> x <- rTraitCont(tree, model="OU", sigma=1, alpha=.3, theta=0, root.value=0)
> mean(x)
[1] 0.3305515
## This is still OK
x <- rTraitCont(tree, model="OU", sigma=1, alpha=3, theta=0, root.value=0)
> mean(x)
[1] 0.01494487
## This is OBVIOUSLY WRONG
x <- rTraitCont(tree, model="OU", sigma=1, alpha=10, theta=0, root.value=0)
mean(x)
[1] -24.13565
What’s happening? rTraitCont numerically integrates: [latex syntax=“display”] x(t_2) = x(t_1) - (t_2-t_1)( x(t_1) - ) + (t_2-t_1) Where t’s are the times at each node and [latex syntax=“inline”]~ N(0,1) [/latex]
The exact equation would be: [latex syntax=“display”] x(t_2) = x(t_1) e{-t}+(1-e{-t}) + ( 1 -e^{-2t} ) . [/latex]
The approximation is fine as long as $ (t_2-t_1) $ is small, which is why we get into trouble with large alpha. While this isn’t implemented, we can meanwhile turn sim.char into a OU simulation by rescaling the tree,
> x <- sim.char(ouTree(tr,alpha=10), matrix(1), root=0)[,1,1]
though it doesn’t let us allow the root and the optimum (theta) to differ.
Another stumbling block I hit came from the way geiger does birth-death simulations:
tr <- birthdeath.tree(b=1, d=0, taxa.stop=100)
x <- sim.char(tr, matrix(1))[,1,1]
fitContinuous(tr, x)
Fitting BM model:
Error in solve.default(phyvcv) :
system is computationally singular: reciprocal condition number = 1.53896e-18
Which doesn’t happen using the birth-death simulated tree instead. The reason is that birthdeath.tree simulation creates a final pair of branches with zero length, while sim.bd.taxa method does not:
> which(tr$edge.length==0)
[1] 163 164
> which(tree$edge.length==0)
integer(0)
Errors that should happen: simulations are not always what you would expect
One theme I draw out in the tutorial is that expectations – averages – aren’t everything. Felsenstein’s example is expected to create an artificial correlation between two traits – it’s not guaranteed: I start the students simulating data on this tree and testing for that correlation, though a substantial fraction won’t find it.
Can likelihood inform the data transform?
> x <- exp(sim.char(tree, matrix(1))[,1,1])
> bm <- fitContinuous(tree, x)
Fitting BM model:
> bm_log <- fitContinuous(tree, log(x))
Fitting BM model:
> bm_log[[1]]$aic
[1] 269.2097
> bm[[1]]$aic
[1] 2137.334
Yup. Why do we continue to look at whether there’s a significant correlation between branch length and contrast? Does not seem a substantial test of model adequacy. We also don’t tend to think of transforms as models.


| 035:027 Khan | : |
See you not that Allah sends down water (rain) from the sky, and We produce therewith fruits of varying colours, and among the mountains are streaks white and red, of varying colours and (others) very black. |
| 035:027 Maulana | : |
Seest thou not that Allah sends down water from the clouds, then We bring forth therewith fruits of various hues? And in the mountains are streaks, white and red, of various hues and (others) intensely black. |
| 035:027 Pickthal | : |
Hast thou not seen that Allah causeth water to fall from the sky, and We produce therewith fruit of divers hues; and among the hills are streaks white and red, of divers hues, and (others) raven-black; |
| 035:027 Rashad | : |
Do you not realize that GOD sends down from the sky water, whereby we produce fruits of various colors? Even the mountains have different colors; the peaks are white, or red, or some other color. And the ravens are black. |
| 035:027 Sarwar | : |
Have you not seen that God has sent water down from the sky, has produced fruits of various colors, and has made streaks of various colors in the mountains, white, red, and intense black. |
| 035:027 Shakir | : |
Do you not see that Allah sends down water from the cloud, then We bring forth therewith fruits of various colors; and in the mountains are streaks, white and red, of various hues and (others) intensely black? |
| 035:027 Sherali | : |
Dost thou not see that ALLAH sends down water from the sky, and WE bring forth therewith fruits of different colours; and in the mountains are streaks white and red, of diverse hues, and others raven black? |
| 035:027 Yusufali | : |
Seest thou not that Allah sends down rain from the sky? With it We then bring out produce of various colours. And in the mountains are tracts white and red, of various shades of colour, and black intense in hue. |
Concepts/Themes Covered: أركان الإسلام > التوحيد > توحيد الله تعالي > وحدانيته Pillars of Islam> Islamic> Oneness of Allah> Singularity and Being Unique الإنسان والعلاقات الاجتماعية > الإنسان > شرفه ودنوه Man and The Social Relations>Man>When Honourable and When Unhonourable العلوم والفنون > الحقائق العلمية و الإشاة إلى وقائع أيدتهاالإكتشافات العلمية > الإشارة إلى طبقات الأرض Science and Art> The Scientific Facts and the Indication to Facts which have been supported by the Scientific Discoveries>Indication to the Earth Strata العلوم والفنون > الحقائق العلمية و الإشاة إلى وقائع أيدتهاالإكتشافات العلمية > الجبال Science and Art> The Scientific Facts and the Indication to Facts which have been supported by the Scientific Discoveries>The Mountains العلوم والفنون > الحقائق العلمية و الإشاة إلى وقائع أيدتهاالإكتشافات العلمية > حقائق في الكون Science and Art> The Scientific Facts and the Indication to Facts which have been supported by the Scientific Discoveries>Facts about the Universe
This tool uses eight English parallel translations for the Holy Quran imported from Mr. Clay Smith. You can also visit Qurany Concepts for browsing the Quran themes or topics. If you want to search the Holy Quran for keywords, please visit Qurany Keywords.