-
Notifications
You must be signed in to change notification settings - Fork 0
/
Model 4.0 - Parent L1 and others at Random.R
216 lines (150 loc) · 10.9 KB
/
Model 4.0 - Parent L1 and others at Random.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# Household-weighted assortment for agent-agent interactions + Parents speak to children in parental L1
### In this world, everyone has an 50% probability of interacting with someone outside their four-person nuclear household and a 50% probability of interacting with someone inside their four-person nuclear household.
### Each parent speaks to both their children in L1, the first language that the parent learned to speak.
### Outside of the specific situation of parents choosing which language to speak to their children, language of conversation is chosen at random: When an individual interacts with someone, they choose their language of conversation by picking at random from among the languages that this individual knows how to speak. Their conversation partner does the same. As a result, many conversations may be conducted bilingually.
# Marry at Random with regard to partner's Languages
# Every year, everyone picks ten conversation partners (with replacement) from the population. Because other agents may also pick them, each agent has an average of 22 conversations each year.
# In every conversation, each partner speaks by picking at random from among their known languages. Conversation partners do not need to coordinate on a single language within their conversation.
#### GENERATE POPULATION DEMOGRAPHY ####
# Generate first parent cohort, all age 25, all monolingual in one of five languages (A-E)
agents <- start_cohort(n = 100, age = 25, n_languages = 5)
# agents <- cbind(agents, first_language)
agents$generation <- 0
# Marry off the first cohort to each other, at random.
agents <- marry_random(agents) %>%
# birth new cohort (children of parent cohort)
birth_new_cohort()
# There are now 200 agents: 100 25-year-old parents, and 100 newborn fraternal twins. One boy and one girl in each family.
# Initialize output table
output <- as.data.frame(matrix(0, nrow = 0, ncol = ncol(agents)))
names(output) <- names(agents)
# set number of generations to run
generations = 5
for(g in seq(generations)){
print(paste("generation", g, sep = " ")) # Loop Counter in console will tell you which generation is growing up right now.
# initialize list of languages spoken by parents to their children
children <- agents[which(agents$generation == max(agents$generation)),] %>%
select(household, agent_id) %>%
rename("child" = "agent_id")
parents <- agents[which(agents$generation == min(agents$generation)),] %>%
select(household, agent_id) %>%
rename("parent" = "agent_id")
# Record parents' first language
first_language <- agents[which(agents$agent_id %in% parents$parent),] %>% select(agent_id, household, age, starts_with("Speaks")) %>%
pivot_longer(cols = starts_with("Speaks"), values_to = "fluency", names_to = "first_language") %>%
filter(!is.na(fluency)) %>%
group_by(agent_id) %>%
filter(age == min(age)) %>%
mutate(L1_count = n(),
number_of_L1s = case_when(L1_count == 1 ~ "monolingual",
L1_count == 2 ~ "bilingual",
L1_count > 2 ~ "multilingual")) %>%
mutate(parent_language = if_else(L1_count == 1, first_language, sample(first_language, size = 1)))
# parent_language$parent_language = parent's L1
parent_language <- merge(first_language, children, by = "household")
# Set years of model run time.
tmax = 25
for(i in seq(tmax)){
print(paste("year", i, sep = " ")) # Loop Counter will appear in the console to let you know how the model run is progressing.
agents$year <- max(agents$year) + 1
#### MAKE AGENTS SPEAK TO EACH OTHER ####
#### Generate conversation dyadic interactions for each agent ####
interaction_matrix <- generate_interactions(agents, n_interactions = 10, own_household_prop = 0.5)
# The value for own_household_prop should result in roughly half of each agent's interactions being with members of their same household. 1/3 of their interactions should be with their parents; 1/6 of their interactions are with their same-aged sibling.
# Now, tally up the full list of conversants/conversations from this matrix.
### Get the interaction list
interaction_list <- get_interaction_lists(interaction_matrix, agents)
# count up the number of 'conversations' had by each agent in this year.
# interactions_per_agent <- sapply(interaction_list, length)
#### Each agent chooses the language they speak in each interaction ####
# This empty list will be populated with the language spoken by each agent in the corresponding position to their agent ID in the interaction_list
language_of_conversation <- list()
for(i in 1:length(interaction_list)){
print(i) # for identifyng where in the for loop code errors are happening.
focal_agent <- as.numeric(names(interaction_list[i])) # identify focal agent
# Identify their family members from the agent trait data frame
family <- agents[which(agents$household == agents[which(agents$agent_id == focal_agent),]$household & agents$agent_id != focal_agent),]
parents <- family[which(family$age > agents[which(agents$agent_id == focal_agent),]$age),] # identify the focal agent's parents
# Step 1: Get agent IDs from the named vector single_agent_interactions
focal_agent_index <- which(agents$agent_id == focal_agent)
agents_in_interaction <- interaction_list[[i]]
# Step 2: Find the indices of agent IDs in interaction_list[1] that are in the 'parents' data frame
parent_indices <- which(agents_in_interaction %in% parents$agent_id)
# Step 3: Find the indices of agent IDs in the vector of interactions that are NOT parents (i.e., everyone else)
other_indices <- which(!(agents_in_interaction %in% parents$agent_id))
# Apply Language Choice Rules
# Step 4: Apply Others Language Choice Rule to non-parent agents: Here, pick at random
#### Non-parents select one of their known languages at random ####
agents_in_interaction[other_indices] <- select_language_at_random_to_speak(agents_in_interaction[other_indices])
# Step 5: Apply Parental Language Choice Rule to Parent Agents: Here, each parent has chosen one of their known languages at random,
# and they will be consistent about speaking this chosen language to this particular child of theirs. They may speak a different language to their other child.
#### Parents speaking to their children with a randomly chosen (but consistently used) language ####
if(length(parent_indices) > 0){
for(j in unique(agents_in_interaction[parent_indices])){
agents_in_interaction[which(agents_in_interaction == j)] <- parent_language[which(parent_language$child == focal_agent & parent_language$agent_id == j),]$parent_language
}
}
language_of_conversation[[i]] <- agents_in_interaction
}
#### AGENTS LEARN LANGUAGES FROM THEIR INTERACTIONS ####
#### Calculate each agent's annual *listening* experience with each language ####
### Tally up agent languages heard, in order to calculate language exposure for focal agents. This will improve their language understanding.
annual_listening_experience <- list()
for(i in 1:length(language_of_conversation)){
annual_listening_experience[[i]] <- calculate_language_exposures(conversation_languages_vector = language_of_conversation[[i]])
}
annual_listening_experience <- as.data.frame(do.call(rbind, annual_listening_experience))
names(annual_listening_experience) <- names(agents %>% select(starts_with("Understands")))
#### Calculate each agent's annual *speaking* experience with each language ####
### Reorganize speaker/spoken lists so each list contains the languages spoken by the focal agent in each of their dyadic exchanges.
#initialize empty list
annual_speaking_experience <- list()
# turn speaker IDs into one long vector for easy indexing
all_speakers <- interaction_list %>% unname() %>% unlist()
# do the same with the matching list of languages spoken in each conversation by each speaker
all_spoken <- language_of_conversation %>% unname() %>% unlist()
# rename a vector for agent IDs, for ease
agent_ids <- names(interaction_list)
# I'm sure there's a way to vectorize this for efficiency, but for now...
languages_spoken <- list()
for(i in 1:length(agent_ids)){
speaker_index <- which(all_speakers == agent_ids[i]) # identify the positions at which this agent is named as a speaker
languages_spoken[[i]] <- all_spoken[speaker_index] # identify the languages they chose to speak on each occasion
}
names(annual_listening_experience) <- names(agents %>% select(starts_with("Understands")))
# Now, tally up each agent's experience speaking each language this year.
#initialize empty list
annual_speaking_experience <- list()
for(i in 1:length(languages_spoken)){
annual_speaking_experience[[i]] <- calculate_language_exposures(conversation_languages_vector = language_of_conversation[[i]])
}
annual_speaking_experience <- as.data.frame(do.call(rbind, annual_speaking_experience))
names(annual_speaking_experience) <- names(agents %>% select(starts_with("Speaks")))
# calculate agent improvements in language speaking
## Note: If you need to adjust the rate of language learning, go change the parameters under the hood for each of these functions. ##
agents <- learn_languages_by_listening(annual_listening_experience)
agents <- learn_languages_by_speaking(annual_speaking_experience)
# update L1 variable.
if(length(agents[which(is.na(agents$first_language)),]$first_language > 0)){ # If anyone is still missing an entry for their first language (L1)
L1_update <- agents[which(is.na(agents$first_language)),] %>% select(agent_id, starts_with("Speaks")) %>%
pivot_longer(cols = starts_with("Speaks"), values_to = "fluency", names_to = "first_language")# then see if they have one yet
first_language <- rbind(first_language, L1_update)
} ### Need to make sure 'speak L1' function can handle Bilinguals....
# add the census for this year to the running total of data output
output <- rbind(output, agents)
# everyone gets one year older
agents$age <- agents$age + 1
# Repeat all of this living for the next value of time t.
}
### In year 26:
# - The parent generation dies
# - The offspring generation marries
# - Each married pair in the offspring generation gives birth to twins; This is now the new parent generation.
# Kill the parent generation
agents <- agents %>%
filter(generation == max(generation))
# Marry off the fully grown cohort to each other, at random.
agents <- marry_random(agents) %>%
# birth new cohort (children of new parent cohort)
birth_new_cohort()
}