Data Wrangling Workshop






Data Wrangling in R: Get all your data and get it tidy


















































Data Wrangling

Broad term, essentially referring to the process of getting your “raw” data into a format you can work with.
Chances are, it might take longer to wrangle your data than it does to actually run your analyses. This motivates us to find ways to wrangle efficiently. We also want to make sure we wrangle our data without errors, as we know for analysis:
GarbageIn -> GarbageOut
We’ll cover a bit of getting all your data together and getting it tidy (Wickham, 2014).

Part I: Get all your data

For Numerous Files, Avoid Copy and Paste

Often, we run into one type of data spread over multiple files. This is common with…
  • Eye-tracking [1 file per participant]
  • SuperLab-based experiments (e.g., self-paced reading, GJTs) [1 file per participant]
  • Longitudinal test score data [1 file per test administration]
  • Longitudinal survey data [1 file per year/semester/etc.]
Handling this manually is not difficult, but it is tedious- imagine copying and pasting 60 spreadsheets into one spreadsheet! The real danger, however, is selectively copying bits from 60 spreadsheets. For example, you might only need a few columns from each SuperLab output file. But this increases the number of manual actions greatly, and thus increases chance of error (such as hitting ctrl-v when you meant to ctrl-c…).
If all of your columns in these files are the same, we have a relatively easy, automated solution in R.

Solution, in 3 Steps

From Wickham (2014):
  1. Read in a list of filenames
  2. Add a column to each file with its name (optional; we’ll skip this today)
  3. Combine all files in a single dataset
Let’s try! We’ll walk through some wrangling from my current project looking at longitudinal oral proficiency development measured by the ACTFL OPIc.

Prep

First, make sure you have the files I sent in a folder on your desktop. In RStudio, click the “Files” tab in the bottom-right window. Click the “…” button and navigate to your desktop folder. Then, click the blue gear icon and select “Set as Working Directory.”
Now we’re ready to start. Click the icon of white square with a plus sign to and choose “R Script.”

Step 1

In the script editor (top-left window), enter the following code.



#first, we load some libraries that we need to use
library(dplyr)
library(tidyr)




#now let's get to the data
#first, we'll make a list of files in our directory
temp <- list.files(pattern = "*.csv")




print(temp)


[1] "wave_1.csv" "wave_2.csv" "wave_3.csv" "wave_4.csv"



Step 3 (remember, we’re skipping step 2, which was optional)

Now that we have a list of files we want to read in, we can start bringing in the data.



#we'll use the lapply (list-apply) function to read in everything on our list
myfiles <- lapply(temp, read.csv, stringsAsFactors = F)
#now we have a list that holds 4 dataframes. We'll put this all into one table.
all <- bind_rows(myfiles)






#and now we have a single table with 4364 observations from 4 different files
head(all)






There are several other ways of doing this (e.g., using a for-loop), but this one is fairly simple. The really nice part of this is that it scales beautifully- whether you have 4 or 400 files, you can get them all in the same file for your analysis without having to open up Excel and cut-and-paste.

Let’s clean things up

While we’re super happy to have successfully gotten all of this data in, we realize that we don’t actually need all of it. Let’s select only the bits we’re interested in:
  • Student.Identification
  • Wave
  • Language
  • Speaking.Score
We’ll use the select() function from the dplyr package to grab these columns.



d <- select(all, 1:3, Speaking.Score)






head(d)






In the select() function, the first argument is the data you’re selecting from, and after that you can list which columns you are grabbing. You can refer to column numbers explicitly call column names (make sure you match case!).
As you can see, we now have 4 variables- just the stuff I’m interested in for my ongoing project that’s looking at oral proficiency development. But we need to do a bit more wrangling, because I’m only interested in identifiable people with at least 2 valid test scores.

Clean out invalid data

If we look at the dataset, we see that some rows are missing IDs, and some are missing scores. Some scores say things like “UR” or “NR”, which indicated that the person took the wrong level of the test and a valid score could not be assigned.
We’ll clear these observations out with dplyr function filter()



#we're going to make a quick list of our valid ACTFL scores
ACTFL <- c("NL","NM","NH","IL","IM","IH","AL","AM","AH","S")
#now the filtering
d <- filter(d, !is.na(Student.Identification), !is.na(Speaking.Score), 
            Speaking.Score %in% ACTFL)






tail(d)






You can see here that we’re down to 3804 observations. We did this by telling filter() to only keep rows with Student.Identification and Speaking.Score that were not (!) NA (missing). We also told it to only keep rows with valid ACTFL scores.

What if you have some duplicate rows?

This can happen with database downloads. In my case, students may have been registered for multiple language classes at the same time, so they had multiple entries in our database. R can easily find and delete duplicate rows with the distinct() function



d <- distinct(d)






tail(d)






…and now we’re down to 3519 observations.

Get only individual with repeated measures

First, let’s arrange the data in a sensible way with the arrange() function:



d <- arrange(d, language, Student.Identification, Wave)






head(d)






What we just did was basically a sorting action like in Excel. In the arrange() function, first we say which data we’re arranging, then we tell the sorting criteria. By default, it uses ascending order, but you can do something like desc(Wave) if you want.
We see that we do indeed have people with 2 or more scores. Hurray! We’re kicking everyone else out by using the group_by() and filter() functions in dplyr. We’ll also use a special operator (%>%) that makes our code a little more concise:



d.rep <- d %>% group_by(Student.Identification) %>% filter(n() > 1)






tail(d.rep)






And here we’re down to 1982 observations. We can see that there are at least 2 observations for each student. This is the data I wanted for my analysis, and now I have a record of how I pulled it. If I got more data later, I could run the same code again.

Part II: Make it tidy

In this part of the workshop, we’ll focus on having a logical structure for datasets, and look at ways to make that happen in R, primarily using the tidyr package.
Datasets are composed of values (or data, sing. datum), and each value is associated with a variable and an observation.
A variable is all the data that measure the same attribute. This could be person IDs (i.e., nominal variables that distinguish one person from another) or things like test scores (e.g., ACTFL OPIc scores that measure speaking ability).
An observation is a collection of all variables belonging to the same object (e.g., person) at the same time/in the same snapshot.
Wickham (2014) argues that data are tidy if:
  1. Each variable has its own column.
  2. Each observation has its own row.
This seems simple, but can be surprisingly tricky in more complicated research (or measurement) designs.

Warm-Up: A Simple Dataset Design

Scenario (based on Loewen et al., in prep): We are interested in the statistical literacy of SLA researchers. We had 89 researchers take a test on statistics, and we have a total score for each person. We also collected some background data, including research orientation (7 point scale, 1 = qual, 7 = quant), number of stats courses taken, and years in the field. We are interested in the relationships between statistical literacy and statistical background.
How would you design this dataset? In groups of 3-4, sketch out a table with values for 1 subject.

Warm-Up: Solution

ID Literacy Score Orientation StatsCourses YearsinField
1 21 6 2 7

Now for a challenge…

Things get a bit more complicated when you are measuring people at different times and with multiple measures of the same attribute- but this is very common in our field. Let’s think about the scenario below, and how we could design a tidy dataset.
Scenario (based on Isbell, Park, & Lee, under review): We were interested in the impact of pronunciation instruction on the comprehensibility of L2 Korean learners. We had 36 students divided into 2 groups: treatment and control. Students differed in their L1 (English, Chinese) and Proficiency (beginner, intermediate). We had them complete 2 tasks (picture description, read-aloud) at 2 times (pretest, posttest). Each task was scored for comprehensibility by several raters, we’ll look at the average score.
How would you design this dataset? In groups of 3-4, sketch out a table with values for 1 subject.

Solution

Student L1 Prof Group Time Task Score
01 E Int T 1 Pic 4.2
01 E Int T 1 Read 5.1
01 E Int T 2 Pic 4.7
01 E Int T 2 Read 6.3
.. . … . . …. .
Although we might intuitively think 1 subject = 1 row, tidy dataset design can turn 1 subject in to dozens of rows. Aside from providing a common reference point for dataset design, it just so happens that lots of stats programs play very nice with tidy data.

Going from wide to long

In R, we can use the gather() function to go from conventional wide datasets to long, tidy datasets.
First, let’s read in our data. You may want to start a new script, but you don’t have to.



library(tidyr)
library(dplyr)
#read in data
df <- read.delim("comprehensibility.txt")






head(df)






So we see here that the comprehensibility scores, which all measure the same attribute, are in 4 different columns. At the same time, we have 4 different measurement instances on the same row; each comprehensibility score is associated with a unique speech sample (task) at a unique time (pre, post).

gather() our comprehensibilty in a single variable column

We need to get all the comprehensibility scores in the same column:



df.long <- gather(df, "Task_Time", "Score", 5:8)
#just to see things easier...
df.long <- arrange(df.long, Subj_ID)






head(df.long)






I decided to make a new dataframe (df.long) so that I could go back to my original wide dataset if needed. In the gather() function, I told it to take the data from “df” (our original dataframe), what the “key” column should be called, what the “value” column should be called, and which columns to pull together (in this case columns 5 to 8).
The pre-gather column names are what goes in the “key” column. Since my column names had information on Task and Time, I called the new key “Task_Time.” The values these are connected to are comprehensibilty “Scores.”
As you can see, we’re not quite done yet- I need to split up that Task_Time column so I can run my analyses.

There’s a function for that, too- separate()

Luckily, tidyr has a function for splitting up confounded columns- separate(). Let’s try it out.



df.long <- separate(df.long, Task_Time, c("Task", "Time"), sep = "_")
#and a sensible ordering...
df.long <- arrange(df.long, Subj_ID, Time, Task)






head(df.long)






And there we have it! From wide to long, ready for all kinds of snazzy graphics and sophisticated repeated-measures analyses.
There’s more that could/should be done with the dataset, like converting variables to factors, creating some recoded variables (from string to number codes), but at the very least our data is in the right shape.

Q&A

Any questions about the functions and examples introduced today?
Any current data problems you’d like to share/brainstorm with the group?

References and Resources

  • Cheatsheets: In RStudio, click the Help drop-down menu at the top of the window. Go to Cheatsheets > Data manipulation with dplyr, tidyr
  • Help Files: If you need some additional reference material for a particular function, type ? in the Console (bottom-left panel). For example, typing ?separate will bring up a help file in the bottom-right panel with some example code.
  • Wickham, H. (2014). Tidy data. Journal of Statistical Software, 59,(10), 1-23. https://www.jstatsoft.org/article/view/v059i10
  • Google. You can use normal question syntax (e.g. “How do you…”) and then add a phrase like “in R” or “with dplyr r”


LS0tDQp0aXRsZTogJ0RhdGEgV3JhbmdsaW5nIGluIFI6IEdldCBhbGwgeW91ciBkYXRhIGFuZCBnZXQgaXQgdGlkeScNCmF1dGhvcjogIkRhbiBJc2JlbGwiDQpvdXRwdXQ6DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojRGF0YSBXcmFuZ2xpbmcNCkJyb2FkIHRlcm0sIGVzc2VudGlhbGx5IHJlZmVycmluZyB0byB0aGUgcHJvY2VzcyBvZiBnZXR0aW5nIHlvdXIgInJhdyIgZGF0YSBpbnRvIGEgZm9ybWF0IHlvdSBjYW4gd29yayB3aXRoLg0KDQpDaGFuY2VzIGFyZSwgaXQgbWlnaHQgdGFrZSBsb25nZXIgdG8gd3JhbmdsZSB5b3VyIGRhdGEgdGhhbiBpdCBkb2VzIHRvIGFjdHVhbGx5IHJ1biB5b3VyIGFuYWx5c2VzLiBUaGlzIG1vdGl2YXRlcw0KdXMgdG8gZmluZCB3YXlzIHRvIHdyYW5nbGUgZWZmaWNpZW50bHkuIFdlIGFsc28gd2FudCB0byBtYWtlIHN1cmUgd2Ugd3JhbmdsZSBvdXIgZGF0YSB3aXRob3V0IGVycm9ycywgYXMgd2Uga25vdw0KZm9yIGFuYWx5c2lzOg0KDQoqR2FyYmFnZUluKiAtPiAqR2FyYmFnZU91dCoNCg0KV2UnbGwgY292ZXIgYSBiaXQgb2YgZ2V0dGluZyBhbGwgeW91ciBkYXRhIHRvZ2V0aGVyIGFuZCBnZXR0aW5nIGl0ICp0aWR5KiAoV2lja2hhbSwgMjAxNCkuDQoNCiNQYXJ0IEk6IEdldCBhbGwgeW91ciBkYXRhDQoNCiNGb3IgTnVtZXJvdXMgRmlsZXMsIEF2b2lkIENvcHkgYW5kIFBhc3RlDQoNCk9mdGVuLCB3ZSBydW4gaW50byBvbmUgdHlwZSBvZiBkYXRhIHNwcmVhZCBvdmVyIG11bHRpcGxlIGZpbGVzLiBUaGlzIGlzIGNvbW1vbiB3aXRoLi4uDQoNCi0gRXllLXRyYWNraW5nIFsxIGZpbGUgcGVyIHBhcnRpY2lwYW50XQ0KDQotIFN1cGVyTGFiLWJhc2VkIGV4cGVyaW1lbnRzIChlLmcuLCBzZWxmLXBhY2VkIHJlYWRpbmcsIEdKVHMpIFsxIGZpbGUgcGVyIHBhcnRpY2lwYW50XQ0KDQotIExvbmdpdHVkaW5hbCB0ZXN0IHNjb3JlIGRhdGEgWzEgZmlsZSBwZXIgdGVzdCBhZG1pbmlzdHJhdGlvbl0NCg0KLSBMb25naXR1ZGluYWwgc3VydmV5IGRhdGEgWzEgZmlsZSBwZXIgeWVhci9zZW1lc3Rlci9ldGMuXQ0KDQpIYW5kbGluZyB0aGlzIG1hbnVhbGx5IGlzIG5vdCBkaWZmaWN1bHQsIGJ1dCBpdCBpcyB0ZWRpb3VzLSBpbWFnaW5lIGNvcHlpbmcgYW5kIHBhc3RpbmcgNjAgc3ByZWFkc2hlZXRzIGludG8gb25lIHNwcmVhZHNoZWV0ISBUaGUgcmVhbCBkYW5nZXIsIGhvd2V2ZXIsIGlzIHNlbGVjdGl2ZWx5IGNvcHlpbmcgYml0cyBmcm9tIDYwIHNwcmVhZHNoZWV0cy4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCBvbmx5IG5lZWQgYSBmZXcgY29sdW1ucyBmcm9tIGVhY2ggU3VwZXJMYWIgb3V0cHV0IGZpbGUuIEJ1dCB0aGlzIGluY3JlYXNlcyB0aGUgbnVtYmVyIG9mIG1hbnVhbCBhY3Rpb25zIGdyZWF0bHksIGFuZCB0aHVzIGluY3JlYXNlcyBjaGFuY2Ugb2YgZXJyb3IgKHN1Y2ggYXMgaGl0dGluZyBjdHJsLXYgd2hlbiB5b3UgbWVhbnQgdG8gY3RybC1jLi4uKS4NCg0KSWYgYWxsIG9mIHlvdXIgY29sdW1ucyBpbiB0aGVzZSBmaWxlcyBhcmUgdGhlIHNhbWUsIHdlIGhhdmUgYSByZWxhdGl2ZWx5IGVhc3ksIGF1dG9tYXRlZCBzb2x1dGlvbiBpbiBSLg0KDQojU29sdXRpb24sIGluIDMgU3RlcHMNCkZyb20gV2lja2hhbSAoMjAxNCk6DQoNCiAgMS4gUmVhZCBpbiBhIGxpc3Qgb2YgZmlsZW5hbWVzDQogIDIuIEFkZCBhIGNvbHVtbiB0byBlYWNoIGZpbGUgd2l0aCBpdHMgbmFtZSAob3B0aW9uYWw7IHdlJ2xsIHNraXAgdGhpcyB0b2RheSkNCiAgMy4gQ29tYmluZSBhbGwgZmlsZXMgaW4gYSBzaW5nbGUgZGF0YXNldA0KDQogIExldCdzIHRyeSEgV2UnbGwgd2FsayB0aHJvdWdoIHNvbWUgd3JhbmdsaW5nIGZyb20gbXkgY3VycmVudCBwcm9qZWN0IGxvb2tpbmcgYXQgbG9uZ2l0dWRpbmFsIG9yYWwgcHJvZmljaWVuY3kgZGV2ZWxvcG1lbnQgbWVhc3VyZWQgYnkgdGhlIEFDVEZMIE9QSWMuDQoNCiNQcmVwDQogIEZpcnN0LCBtYWtlIHN1cmUgeW91IGhhdmUgdGhlIGZpbGVzIEkgc2VudCBpbiBhIGZvbGRlciBvbiB5b3VyIGRlc2t0b3AuDQogIEluIFJTdHVkaW8sIGNsaWNrIHRoZSAiRmlsZXMiIHRhYiBpbiB0aGUgYm90dG9tLXJpZ2h0IHdpbmRvdy4gQ2xpY2sgdGhlICIuLi4iIGJ1dHRvbiBhbmQgbmF2aWdhdGUgdG8geW91cg0KICBkZXNrdG9wIGZvbGRlci4gVGhlbiwgY2xpY2sgdGhlIGJsdWUgZ2VhciBpY29uIGFuZCBzZWxlY3QgIlNldCBhcyBXb3JraW5nIERpcmVjdG9yeS4iDQogIA0KICBOb3cgd2UncmUgcmVhZHkgdG8gc3RhcnQuIENsaWNrIHRoZSBpY29uIG9mIHdoaXRlIHNxdWFyZSB3aXRoIGEgcGx1cyBzaWduIHRvIGFuZCBjaG9vc2UgIlIgU2NyaXB0LiINCiAgDQojU3RlcCAxDQogIA0KICBJbiB0aGUgc2NyaXB0IGVkaXRvciAodG9wLWxlZnQgd2luZG93KSwgZW50ZXIgdGhlIGZvbGxvd2luZyBjb2RlLg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCg0KI2ZpcnN0LCB3ZSBsb2FkIHNvbWUgbGlicmFyaWVzIHRoYXQgd2UgbmVlZCB0byB1c2UNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KYGBgDQpgYGB7cn0NCiNub3cgbGV0J3MgZ2V0IHRvIHRoZSBkYXRhDQojZmlyc3QsIHdlJ2xsIG1ha2UgYSBsaXN0IG9mIGZpbGVzIGluIG91ciBkaXJlY3RvcnkNCnRlbXAgPC0gbGlzdC5maWxlcyhwYXR0ZXJuID0gIiouY3N2IikNCg0KYGBgDQpgYGB7cn0NCnByaW50KHRlbXApDQpgYGANCg0KDQojU3RlcCAzIChyZW1lbWJlciwgd2UncmUgc2tpcHBpbmcgc3RlcCAyLCB3aGljaCB3YXMgb3B0aW9uYWwpDQpOb3cgdGhhdCB3ZSBoYXZlIGEgbGlzdCBvZiBmaWxlcyB3ZSB3YW50IHRvIHJlYWQgaW4sIHdlIGNhbiBzdGFydCBicmluZ2luZyBpbiB0aGUgZGF0YS4NCg0KYGBge3J9DQoNCiN3ZSdsbCB1c2UgdGhlIGxhcHBseSAobGlzdC1hcHBseSkgZnVuY3Rpb24gdG8gcmVhZCBpbiBldmVyeXRoaW5nIG9uIG91ciBsaXN0DQpteWZpbGVzIDwtIGxhcHBseSh0ZW1wLCByZWFkLmNzdiwgc3RyaW5nc0FzRmFjdG9ycyA9IEYpDQoNCiNub3cgd2UgaGF2ZSBhIGxpc3QgdGhhdCBob2xkcyA0IGRhdGFmcmFtZXMuIFdlJ2xsIHB1dCB0aGlzIGFsbCBpbnRvIG9uZSB0YWJsZS4NCmFsbCA8LSBiaW5kX3Jvd3MobXlmaWxlcykNCg0KYGBgDQoNCmBgYHtyfQ0KI2FuZCBub3cgd2UgaGF2ZSBhIHNpbmdsZSB0YWJsZSB3aXRoIDQzNjQgb2JzZXJ2YXRpb25zIGZyb20gNCBkaWZmZXJlbnQgZmlsZXMNCmhlYWQoYWxsKQ0KYGBgDQoNCg0KVGhlcmUgYXJlIHNldmVyYWwgb3RoZXIgd2F5cyBvZiBkb2luZyB0aGlzIChlLmcuLCB1c2luZyBhIGZvci1sb29wKSwgYnV0IHRoaXMgb25lIGlzIGZhaXJseSBzaW1wbGUuIFRoZSByZWFsbHkgbmljZQ0KcGFydCBvZiB0aGlzIGlzIHRoYXQgaXQgc2NhbGVzIGJlYXV0aWZ1bGx5LSB3aGV0aGVyIHlvdSBoYXZlIDQgb3IgNDAwIGZpbGVzLCB5b3UgY2FuIGdldCB0aGVtIGFsbCBpbiB0aGUgc2FtZSBmaWxlDQpmb3IgeW91ciBhbmFseXNpcyB3aXRob3V0IGhhdmluZyB0byBvcGVuIHVwIEV4Y2VsIGFuZCBjdXQtYW5kLXBhc3RlLg0KDQojTGV0J3MgY2xlYW4gdGhpbmdzIHVwDQpXaGlsZSB3ZSdyZSBzdXBlciBoYXBweSB0byBoYXZlIHN1Y2Nlc3NmdWxseSBnb3R0ZW4gYWxsIG9mIHRoaXMgZGF0YSBpbiwgd2UgcmVhbGl6ZSB0aGF0IHdlIGRvbid0IGFjdHVhbGx5IG5lZWQgDQphbGwgb2YgaXQuIExldCdzIHNlbGVjdCBvbmx5IHRoZSBiaXRzIHdlJ3JlIGludGVyZXN0ZWQgaW46DQoNCi0gU3R1ZGVudC5JZGVudGlmaWNhdGlvbg0KLSBXYXZlDQotIExhbmd1YWdlDQotIFNwZWFraW5nLlNjb3JlDQoNCldlJ2xsIHVzZSB0aGUgc2VsZWN0KCkgZnVuY3Rpb24gZnJvbSB0aGUgZHBseXIgcGFja2FnZSB0byBncmFiIHRoZXNlIGNvbHVtbnMuDQoNCmBgYHtyfQ0KDQpkIDwtIHNlbGVjdChhbGwsIDE6MywgU3BlYWtpbmcuU2NvcmUpDQpgYGANCg0KDQpgYGB7cn0NCg0KaGVhZChkKQ0KDQpgYGANCkluIHRoZSBzZWxlY3QoKSBmdW5jdGlvbiwgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIHRoZSBkYXRhIHlvdSdyZSBzZWxlY3RpbmcgZnJvbSwgYW5kIGFmdGVyIHRoYXQgeW91IGNhbiBsaXN0IHdoaWNoIGNvbHVtbnMNCnlvdSBhcmUgZ3JhYmJpbmcuIFlvdSBjYW4gcmVmZXIgdG8gY29sdW1uIG51bWJlcnMgZXhwbGljaXRseSBjYWxsIGNvbHVtbiBuYW1lcyAobWFrZSBzdXJlIHlvdSBtYXRjaCBjYXNlISkuDQoNCkFzIHlvdSBjYW4gc2VlLCB3ZSBub3cgaGF2ZSA0IHZhcmlhYmxlcy0ganVzdCB0aGUgc3R1ZmYgSSdtIGludGVyZXN0ZWQgaW4gZm9yIG15IG9uZ29pbmcgcHJvamVjdCB0aGF0J3MgbG9va2luZyBhdCBvcmFsIA0KcHJvZmljaWVuY3kgZGV2ZWxvcG1lbnQuIEJ1dCB3ZSBuZWVkIHRvIGRvIGEgYml0IG1vcmUgd3JhbmdsaW5nLCBiZWNhdXNlIEknbSBvbmx5IGludGVyZXN0ZWQgaW4gKippZGVudGlmaWFibGUqKiBwZW9wbGUgd2l0aCBhdCBsZWFzdCAyICoqdmFsaWQqKiB0ZXN0IHNjb3Jlcy4NCg0KI0NsZWFuIG91dCBpbnZhbGlkIGRhdGENCklmIHdlIGxvb2sgYXQgdGhlIGRhdGFzZXQsIHdlIHNlZSB0aGF0IHNvbWUgcm93cyBhcmUgbWlzc2luZyBJRHMsIGFuZCBzb21lIGFyZSBtaXNzaW5nIHNjb3Jlcy4gU29tZSBzY29yZXMgc2F5IHRoaW5ncyBsaWtlICJVUiIgb3IgIk5SIiwgd2hpY2ggaW5kaWNhdGVkIHRoYXQgdGhlIHBlcnNvbiB0b29rIHRoZSB3cm9uZyBsZXZlbCBvZiB0aGUgdGVzdCBhbmQgYSB2YWxpZCBzY29yZSBjb3VsZCBub3QgYmUgYXNzaWduZWQuDQoNCldlJ2xsIGNsZWFyIHRoZXNlIG9ic2VydmF0aW9ucyBvdXQgd2l0aCBkcGx5ciBmdW5jdGlvbiBmaWx0ZXIoKQ0KDQpgYGB7cn0NCg0KI3dlJ3JlIGdvaW5nIHRvIG1ha2UgYSBxdWljayBsaXN0IG9mIG91ciB2YWxpZCBBQ1RGTCBzY29yZXMNCkFDVEZMIDwtIGMoIk5MIiwiTk0iLCJOSCIsIklMIiwiSU0iLCJJSCIsIkFMIiwiQU0iLCJBSCIsIlMiKQ0KDQojbm93IHRoZSBmaWx0ZXJpbmcNCmQgPC0gZmlsdGVyKGQsICFpcy5uYShTdHVkZW50LklkZW50aWZpY2F0aW9uKSwgIWlzLm5hKFNwZWFraW5nLlNjb3JlKSwgDQogICAgICAgICAgICBTcGVha2luZy5TY29yZSAlaW4lIEFDVEZMKQ0KYGBgDQoNCg0KYGBge3J9DQp0YWlsKGQpDQpgYGANCllvdSBjYW4gc2VlIGhlcmUgdGhhdCB3ZSdyZSBkb3duIHRvIDM4MDQgb2JzZXJ2YXRpb25zLiBXZSBkaWQgdGhpcyBieSB0ZWxsaW5nIGZpbHRlcigpIHRvIG9ubHkga2VlcCByb3dzIHdpdGggU3R1ZGVudC5JZGVudGlmaWNhdGlvbiBhbmQgU3BlYWtpbmcuU2NvcmUgdGhhdCB3ZXJlICoqbm90KiogKCEpIE5BIChtaXNzaW5nKS4gV2UgYWxzbyB0b2xkIGl0IHRvIG9ubHkga2VlcCByb3dzIHdpdGggdmFsaWQgQUNURkwgc2NvcmVzLg0KDQojV2hhdCBpZiB5b3UgaGF2ZSBzb21lIGR1cGxpY2F0ZSByb3dzPw0KVGhpcyBjYW4gaGFwcGVuIHdpdGggZGF0YWJhc2UgZG93bmxvYWRzLiBJbiBteSBjYXNlLCBzdHVkZW50cyBtYXkgaGF2ZSBiZWVuIHJlZ2lzdGVyZWQgZm9yIG11bHRpcGxlIGxhbmd1YWdlIGNsYXNzZXMgYXQgdGhlIHNhbWUgdGltZSwgc28gdGhleSBoYWQgbXVsdGlwbGUgZW50cmllcyBpbiBvdXIgZGF0YWJhc2UuIFIgY2FuIGVhc2lseSBmaW5kIGFuZCBkZWxldGUgZHVwbGljYXRlIHJvd3Mgd2l0aCB0aGUgZGlzdGluY3QoKSBmdW5jdGlvbg0KDQpgYGB7cn0NCmQgPC0gZGlzdGluY3QoZCkNCmBgYA0KDQoNCmBgYHtyfQ0KdGFpbChkKQ0KYGBgDQouLi5hbmQgbm93IHdlJ3JlIGRvd24gdG8gMzUxOSBvYnNlcnZhdGlvbnMuDQoNCiNHZXQgb25seSBpbmRpdmlkdWFsIHdpdGggcmVwZWF0ZWQgbWVhc3VyZXMNCkZpcnN0LCBsZXQncyBhcnJhbmdlIHRoZSBkYXRhIGluIGEgc2Vuc2libGUgd2F5IHdpdGggdGhlIGFycmFuZ2UoKSBmdW5jdGlvbjoNCg0KYGBge3J9DQpkIDwtIGFycmFuZ2UoZCwgbGFuZ3VhZ2UsIFN0dWRlbnQuSWRlbnRpZmljYXRpb24sIFdhdmUpDQpgYGANCg0KDQpgYGB7cn0NCmhlYWQoZCkNCmBgYA0KV2hhdCB3ZSBqdXN0IGRpZCB3YXMgYmFzaWNhbGx5IGEgc29ydGluZyBhY3Rpb24gbGlrZSBpbiBFeGNlbC4gSW4gdGhlIGFycmFuZ2UoKSBmdW5jdGlvbiwgZmlyc3Qgd2Ugc2F5IHdoaWNoIGRhdGEgd2UncmUgYXJyYW5naW5nLCB0aGVuIHdlIHRlbGwgdGhlIHNvcnRpbmcgY3JpdGVyaWEuIEJ5IGRlZmF1bHQsIGl0IHVzZXMgYXNjZW5kaW5nIG9yZGVyLCBidXQgeW91IGNhbiBkbyBzb21ldGhpbmcgbGlrZSBkZXNjKFdhdmUpIGlmIHlvdSB3YW50Lg0KDQpXZSBzZWUgdGhhdCB3ZSBkbyBpbmRlZWQgaGF2ZSBwZW9wbGUgd2l0aCAyIG9yIG1vcmUgc2NvcmVzLiBIdXJyYXkhIFdlJ3JlIGtpY2tpbmcgZXZlcnlvbmUgZWxzZSBvdXQgYnkgdXNpbmcgdGhlIGdyb3VwX2J5KCkgYW5kIGZpbHRlcigpIGZ1bmN0aW9ucyBpbiBkcGx5ci4gV2UnbGwgYWxzbyB1c2UgYSBzcGVjaWFsIG9wZXJhdG9yICglPiUpIHRoYXQgbWFrZXMgb3VyIGNvZGUgYSBsaXR0bGUgbW9yZSBjb25jaXNlOg0KDQpgYGB7cn0NCmQucmVwIDwtIGQgJT4lIGdyb3VwX2J5KFN0dWRlbnQuSWRlbnRpZmljYXRpb24pICU+JSBmaWx0ZXIobigpID4gMSkNCmBgYA0KDQoNCmBgYHtyfQ0KdGFpbChkLnJlcCkNCmBgYA0KQW5kIGhlcmUgd2UncmUgZG93biB0byAxOTgyIG9ic2VydmF0aW9ucy4gV2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSBhdCBsZWFzdCAyIG9ic2VydmF0aW9ucyBmb3IgZWFjaCBzdHVkZW50LiBUaGlzIGlzIHRoZSBkYXRhIEkgd2FudGVkIGZvciBteSBhbmFseXNpcywgYW5kIG5vdyBJIGhhdmUgYSByZWNvcmQgb2YgaG93IEkgcHVsbGVkIGl0LiBJZiBJIGdvdCBtb3JlIGRhdGEgbGF0ZXIsIEkgY291bGQgcnVuIHRoZSBzYW1lIGNvZGUgYWdhaW4uDQoNCiNQYXJ0IElJOiBNYWtlIGl0ICp0aWR5Kg0KDQpJbiB0aGlzIHBhcnQgb2YgdGhlIHdvcmtzaG9wLCB3ZSdsbCBmb2N1cyBvbiBoYXZpbmcgYSBsb2dpY2FsIHN0cnVjdHVyZSBmb3IgZGF0YXNldHMsIGFuZCBsb29rIGF0IHdheXMgdG8gbWFrZSB0aGF0IGhhcHBlbiBpbiBSLCBwcmltYXJpbHkgdXNpbmcgdGhlICp0aWR5ciogcGFja2FnZS4NCg0KRGF0YXNldHMgYXJlIGNvbXBvc2VkIG9mICp2YWx1ZXMqIChvciAqZGF0YSosIHNpbmcuICpkYXR1bSopLCBhbmQgZWFjaCAqdmFsdWUqIGlzIGFzc29jaWF0ZWQgd2l0aCBhICp2YXJpYWJsZSogYW5kIGFuICpvYnNlcnZhdGlvbiouDQoNCkEgKnZhcmlhYmxlKiBpcyBhbGwgdGhlIGRhdGEgdGhhdCBtZWFzdXJlIHRoZSBzYW1lIGF0dHJpYnV0ZS4gVGhpcyBjb3VsZCBiZSBwZXJzb24gSURzIChpLmUuLCBub21pbmFsIHZhcmlhYmxlcyB0aGF0IGRpc3Rpbmd1aXNoIG9uZSBwZXJzb24gZnJvbSBhbm90aGVyKSBvciB0aGluZ3MgbGlrZSB0ZXN0IHNjb3JlcyAoZS5nLiwgQUNURkwgT1BJYyBzY29yZXMgdGhhdCBtZWFzdXJlIHNwZWFraW5nIGFiaWxpdHkpLg0KDQpBbiAqb2JzZXJ2YXRpb24qIGlzIGEgY29sbGVjdGlvbiBvZiBhbGwgdmFyaWFibGVzIGJlbG9uZ2luZyB0byB0aGUgc2FtZSBvYmplY3QgKGUuZy4sIHBlcnNvbikgKmF0IHRoZSBzYW1lIHRpbWUvaW4gdGhlIHNhbWUgc25hcHNob3QqLg0KDQpXaWNraGFtICgyMDE0KSBhcmd1ZXMgdGhhdCBkYXRhIGFyZSAqdGlkeSogaWY6DQoNCjEuIEVhY2ggdmFyaWFibGUgaGFzIGl0cyBvd24gY29sdW1uLg0KMi4gRWFjaCBvYnNlcnZhdGlvbiBoYXMgaXRzIG93biByb3cuDQoNClRoaXMgc2VlbXMgc2ltcGxlLCBidXQgY2FuIGJlIHN1cnByaXNpbmdseSB0cmlja3kgaW4gbW9yZSBjb21wbGljYXRlZCByZXNlYXJjaCAob3IgbWVhc3VyZW1lbnQpIGRlc2lnbnMuDQoNCiNXYXJtLVVwOiBBIFNpbXBsZSBEYXRhc2V0IERlc2lnbg0KDQpTY2VuYXJpbyAoYmFzZWQgb24gTG9ld2VuIGV0IGFsLiwgaW4gcHJlcCk6IFdlIGFyZSBpbnRlcmVzdGVkIGluIHRoZSBzdGF0aXN0aWNhbCBsaXRlcmFjeSBvZiBTTEEgcmVzZWFyY2hlcnMuIFdlIGhhZCA4OSByZXNlYXJjaGVycyB0YWtlIGEgdGVzdCBvbiBzdGF0aXN0aWNzLCBhbmQgd2UgaGF2ZSBhIHRvdGFsIHNjb3JlIGZvciBlYWNoIHBlcnNvbi4gV2UgYWxzbyBjb2xsZWN0ZWQgc29tZSBiYWNrZ3JvdW5kIGRhdGEsIGluY2x1ZGluZyByZXNlYXJjaCBvcmllbnRhdGlvbiAoNyBwb2ludCBzY2FsZSwgMSA9IHF1YWwsIDcgPSBxdWFudCksIG51bWJlciBvZiBzdGF0cyBjb3Vyc2VzIHRha2VuLCBhbmQgeWVhcnMgaW4gdGhlIGZpZWxkLiBXZSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHN0YXRpc3RpY2FsIGxpdGVyYWN5IGFuZCBzdGF0aXN0aWNhbCBiYWNrZ3JvdW5kLg0KDQpIb3cgd291bGQgeW91IGRlc2lnbiB0aGlzIGRhdGFzZXQ/IEluIGdyb3VwcyBvZiAzLTQsIHNrZXRjaCBvdXQgYSB0YWJsZSB3aXRoIHZhbHVlcyBmb3IgMSBzdWJqZWN0Lg0KDQojV2FybS1VcDogU29sdXRpb24NCg0KSUQgfCBMaXRlcmFjeSBTY29yZSB8IE9yaWVudGF0aW9uIHwgU3RhdHNDb3Vyc2VzIHwgWWVhcnNpbkZpZWxkDQotLS18LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0NCjEgIHwyMSAgICAgICAgICAgICAgfDYgICAgICAgICAgICB8MiAgICAgICAgICAgICB8Nw0KDQojTm93IGZvciBhIGNoYWxsZW5nZS4uLg0KVGhpbmdzIGdldCBhIGJpdCBtb3JlIGNvbXBsaWNhdGVkIHdoZW4geW91IGFyZSBtZWFzdXJpbmcgcGVvcGxlIGF0IGRpZmZlcmVudCB0aW1lcyBhbmQgd2l0aCBtdWx0aXBsZSBtZWFzdXJlcyBvZiB0aGUgc2FtZSBhdHRyaWJ1dGUtIGJ1dCB0aGlzIGlzICp2ZXJ5KiBjb21tb24gaW4gb3VyIGZpZWxkLiBMZXQncyB0aGluayBhYm91dCB0aGUgc2NlbmFyaW8gYmVsb3csIGFuZCBob3cgd2UgY291bGQgZGVzaWduIGEgKnRpZHkqIGRhdGFzZXQuDQoNClNjZW5hcmlvIChiYXNlZCBvbiBJc2JlbGwsIFBhcmssICYgTGVlLCB1bmRlciByZXZpZXcpOiBXZSB3ZXJlIGludGVyZXN0ZWQgaW4gdGhlIGltcGFjdCBvZiBwcm9udW5jaWF0aW9uIGluc3RydWN0aW9uIG9uIHRoZSBjb21wcmVoZW5zaWJpbGl0eSBvZiBMMiBLb3JlYW4gbGVhcm5lcnMuIFdlIGhhZCAzNiAqKnN0dWRlbnRzKiogZGl2aWRlZCBpbnRvIDIgKipncm91cCoqczogdHJlYXRtZW50IGFuZCBjb250cm9sLiBTdHVkZW50cyBkaWZmZXJlZCBpbiB0aGVpciAqKkwxKiogKEVuZ2xpc2gsIENoaW5lc2UpIGFuZCAqKlByb2ZpY2llbmN5KiogKGJlZ2lubmVyLCBpbnRlcm1lZGlhdGUpLiBXZSBoYWQgdGhlbSBjb21wbGV0ZSAyICoqdGFzayoqcyAocGljdHVyZSBkZXNjcmlwdGlvbiwgcmVhZC1hbG91ZCkgYXQgMiAqKnRpbWUqKnMgKHByZXRlc3QsIHBvc3R0ZXN0KS4gRWFjaCB0YXNrIHdhcyBzY29yZWQgZm9yIGNvbXByZWhlbnNpYmlsaXR5IGJ5IHNldmVyYWwgcmF0ZXJzLCB3ZSdsbCBsb29rIGF0IHRoZSBhdmVyYWdlICoqc2NvcmUqKi4NCg0KSG93IHdvdWxkIHlvdSBkZXNpZ24gdGhpcyBkYXRhc2V0PyBJbiBncm91cHMgb2YgMy00LCBza2V0Y2ggb3V0IGEgdGFibGUgd2l0aCB2YWx1ZXMgZm9yIDEgc3ViamVjdC4NCg0KI1NvbHV0aW9uDQoNClN0dWRlbnR8TDF8UHJvZnxHcm91cHxUaW1lfFRhc2t8U2NvcmUNCi0tLS0tLS18LS18LS0tLXwtLS0tLXwtLS0tfC0tLS18LS0tLS0NCjAxfEV8SW50fFR8MXxQaWN8NC4yDQowMXxFfEludHxUfDF8UmVhZHw1LjENCjAxfEV8SW50fFR8MnxQaWN8NC43DQowMXxFfEludHxUfDJ8UmVhZHw2LjMNCi4ufC58Li4ufC58LnwuLi4ufC4NCg0KQWx0aG91Z2ggd2UgbWlnaHQgaW50dWl0aXZlbHkgdGhpbmsgMSBzdWJqZWN0ID0gMSByb3csICp0aWR5KiBkYXRhc2V0IGRlc2lnbiBjYW4gdHVybiAxIHN1YmplY3QgaW4gdG8gZG96ZW5zIG9mIHJvd3MuIEFzaWRlIGZyb20gcHJvdmlkaW5nIGEgY29tbW9uIHJlZmVyZW5jZSBwb2ludCBmb3IgZGF0YXNldCBkZXNpZ24sIGl0IGp1c3Qgc28gaGFwcGVucyB0aGF0IGxvdHMgb2Ygc3RhdHMgcHJvZ3JhbXMgcGxheSB2ZXJ5IG5pY2Ugd2l0aCB0aWR5IGRhdGEuDQoNCiNHb2luZyBmcm9tIHdpZGUgdG8gbG9uZw0KDQpJbiBSLCB3ZSBjYW4gdXNlIHRoZSBnYXRoZXIoKSBmdW5jdGlvbiB0byBnbyBmcm9tIGNvbnZlbnRpb25hbCB3aWRlIGRhdGFzZXRzIHRvIGxvbmcsIHRpZHkgZGF0YXNldHMuDQoNCkZpcnN0LCBsZXQncyByZWFkIGluIG91ciBkYXRhLiBZb3UgbWF5IHdhbnQgdG8gc3RhcnQgYSBuZXcgc2NyaXB0LCBidXQgeW91IGRvbid0IGhhdmUgdG8uDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoZHBseXIpDQoNCiNyZWFkIGluIGRhdGENCmRmIDwtIHJlYWQuZGVsaW0oImNvbXByZWhlbnNpYmlsaXR5LnR4dCIpDQpgYGANCg0KYGBge3J9DQpoZWFkKGRmKQ0KYGBgDQpTbyB3ZSBzZWUgaGVyZSB0aGF0IHRoZSBjb21wcmVoZW5zaWJpbGl0eSBzY29yZXMsIHdoaWNoIGFsbCBtZWFzdXJlIHRoZSBzYW1lIGF0dHJpYnV0ZSwgYXJlIGluIDQgZGlmZmVyZW50IGNvbHVtbnMuIEF0IHRoZSBzYW1lIHRpbWUsIHdlIGhhdmUgNCBkaWZmZXJlbnQgbWVhc3VyZW1lbnQgaW5zdGFuY2VzIG9uIHRoZSBzYW1lIHJvdzsgZWFjaCBjb21wcmVoZW5zaWJpbGl0eSBzY29yZSBpcyBhc3NvY2lhdGVkIHdpdGggYSB1bmlxdWUgc3BlZWNoIHNhbXBsZSAodGFzaykgYXQgYSB1bmlxdWUgdGltZSAocHJlLCBwb3N0KS4gDQoNCiNnYXRoZXIoKSBvdXIgY29tcHJlaGVuc2liaWx0eSBpbiBhIHNpbmdsZSB2YXJpYWJsZSBjb2x1bW4NCldlIG5lZWQgdG8gZ2V0IGFsbCB0aGUgY29tcHJlaGVuc2liaWxpdHkgc2NvcmVzIGluIHRoZSBzYW1lIGNvbHVtbjoNCg0KYGBge3J9DQpkZi5sb25nIDwtIGdhdGhlcihkZiwgIlRhc2tfVGltZSIsICJTY29yZSIsIDU6OCkNCg0KI2p1c3QgdG8gc2VlIHRoaW5ncyBlYXNpZXIuLi4NCmRmLmxvbmcgPC0gYXJyYW5nZShkZi5sb25nLCBTdWJqX0lEKQ0KYGBgDQoNCmBgYHtyfQ0KaGVhZChkZi5sb25nKQ0KYGBgDQoNCkkgZGVjaWRlZCB0byBtYWtlIGEgbmV3IGRhdGFmcmFtZSAoZGYubG9uZykgc28gdGhhdCBJIGNvdWxkIGdvIGJhY2sgdG8gbXkgb3JpZ2luYWwgd2lkZSBkYXRhc2V0IGlmIG5lZWRlZC4gSW4gdGhlIGdhdGhlcigpIGZ1bmN0aW9uLCBJIHRvbGQgaXQgdG8gdGFrZSB0aGUgZGF0YSBmcm9tICJkZiIgKG91ciBvcmlnaW5hbCBkYXRhZnJhbWUpLCB3aGF0IHRoZSAia2V5IiBjb2x1bW4gc2hvdWxkIGJlIGNhbGxlZCwgd2hhdCB0aGUgInZhbHVlIiBjb2x1bW4gc2hvdWxkIGJlIGNhbGxlZCwgYW5kIHdoaWNoIGNvbHVtbnMgdG8gcHVsbCB0b2dldGhlciAoaW4gdGhpcyBjYXNlIGNvbHVtbnMgNSB0byA4KS4gDQoNClRoZSBwcmUtZ2F0aGVyIGNvbHVtbiBuYW1lcyBhcmUgd2hhdCBnb2VzIGluIHRoZSAia2V5IiBjb2x1bW4uIFNpbmNlIG15IGNvbHVtbiBuYW1lcyBoYWQgaW5mb3JtYXRpb24gb24gVGFzayBhbmQgVGltZSwgSSBjYWxsZWQgdGhlIG5ldyBrZXkgIlRhc2tfVGltZS4iIFRoZSB2YWx1ZXMgdGhlc2UgYXJlIGNvbm5lY3RlZCB0byBhcmUgY29tcHJlaGVuc2liaWx0eSAiU2NvcmVzLiINCg0KQXMgeW91IGNhbiBzZWUsIHdlJ3JlIG5vdCBxdWl0ZSBkb25lIHlldC0gSSBuZWVkIHRvIHNwbGl0IHVwIHRoYXQgVGFza19UaW1lIGNvbHVtbiBzbyBJIGNhbiBydW4gbXkgYW5hbHlzZXMuDQoNCiNUaGVyZSdzIGEgZnVuY3Rpb24gZm9yIHRoYXQsIHRvby0gc2VwYXJhdGUoKQ0KTHVja2lseSwgKnRpZHlyKiBoYXMgYSBmdW5jdGlvbiBmb3Igc3BsaXR0aW5nIHVwIGNvbmZvdW5kZWQgY29sdW1ucy0gc2VwYXJhdGUoKS4gTGV0J3MgdHJ5IGl0IG91dC4NCg0KYGBge3J9DQpkZi5sb25nIDwtIHNlcGFyYXRlKGRmLmxvbmcsIFRhc2tfVGltZSwgYygiVGFzayIsICJUaW1lIiksIHNlcCA9ICJfIikNCg0KI2FuZCBhIHNlbnNpYmxlIG9yZGVyaW5nLi4uDQpkZi5sb25nIDwtIGFycmFuZ2UoZGYubG9uZywgU3Vial9JRCwgVGltZSwgVGFzaykNCmBgYA0KDQpgYGB7cn0NCmhlYWQoZGYubG9uZykNCmBgYA0KDQpBbmQgdGhlcmUgd2UgaGF2ZSBpdCEgRnJvbSB3aWRlIHRvIGxvbmcsIHJlYWR5IGZvciBhbGwga2luZHMgb2Ygc25henp5IGdyYXBoaWNzIGFuZCBzb3BoaXN0aWNhdGVkIHJlcGVhdGVkLW1lYXN1cmVzIGFuYWx5c2VzLg0KDQpUaGVyZSdzIG1vcmUgdGhhdCBjb3VsZC9zaG91bGQgYmUgZG9uZSB3aXRoIHRoZSBkYXRhc2V0LCBsaWtlIGNvbnZlcnRpbmcgdmFyaWFibGVzIHRvIGZhY3RvcnMsIGNyZWF0aW5nIHNvbWUgcmVjb2RlZCB2YXJpYWJsZXMgKGZyb20gc3RyaW5nIHRvIG51bWJlciBjb2RlcyksIGJ1dCBhdCB0aGUgdmVyeSBsZWFzdCBvdXIgZGF0YSBpcyBpbiB0aGUgcmlnaHQgc2hhcGUuDQoNCiNRJkENCg0KQW55IHF1ZXN0aW9ucyBhYm91dCB0aGUgZnVuY3Rpb25zIGFuZCBleGFtcGxlcyBpbnRyb2R1Y2VkIHRvZGF5Pw0KDQpBbnkgY3VycmVudCBkYXRhIHByb2JsZW1zIHlvdSdkIGxpa2UgdG8gc2hhcmUvYnJhaW5zdG9ybSB3aXRoIHRoZSBncm91cD8NCg0KI1JlZmVyZW5jZXMgYW5kIFJlc291cmNlcw0KDQotIENoZWF0c2hlZXRzOiBJbiBSU3R1ZGlvLCBjbGljayB0aGUgSGVscCBkcm9wLWRvd24gbWVudSBhdCB0aGUgdG9wIG9mIHRoZSB3aW5kb3cuIEdvIHRvIENoZWF0c2hlZXRzID4gRGF0YSBtYW5pcHVsYXRpb24gd2l0aCBkcGx5ciwgdGlkeXINCg0KLSBIZWxwIEZpbGVzOiBJZiB5b3UgbmVlZCBzb21lIGFkZGl0aW9uYWwgcmVmZXJlbmNlIG1hdGVyaWFsIGZvciBhIHBhcnRpY3VsYXIgZnVuY3Rpb24sIHR5cGUgPzxmdW5jdGlvbj4gaW4gdGhlIENvbnNvbGUgKGJvdHRvbS1sZWZ0IHBhbmVsKS4gRm9yIGV4YW1wbGUsIHR5cGluZyA/c2VwYXJhdGUgd2lsbCBicmluZyB1cCBhIGhlbHAgZmlsZSBpbiB0aGUgYm90dG9tLXJpZ2h0IHBhbmVsIHdpdGggc29tZSBleGFtcGxlIGNvZGUuDQoNCi0gV2lja2hhbSwgSC4gKDIwMTQpLiBUaWR5IGRhdGEuICpKb3VybmFsIG9mIFN0YXRpc3RpY2FsIFNvZnR3YXJlLCA1OSwqKDEwKSwgMS0yMy4gIFtodHRwczovL3d3dy5qc3RhdHNvZnQub3JnL2FydGljbGUvdmlldy92MDU5aTEwXShodHRwczovL3d3dy5qc3RhdHNvZnQub3JnL2FydGljbGUvdmlldy92MDU5aTEwKQ0KDQotIEdvb2dsZS4gWW91IGNhbiB1c2Ugbm9ybWFsIHF1ZXN0aW9uIHN5bnRheCAoZS5nLiAiSG93IGRvIHlvdS4uLiIpIGFuZCB0aGVuIGFkZCBhIHBocmFzZSBsaWtlICJpbiBSIiBvciAid2l0aCBkcGx5ciByIg0K










An Alexa for language learning

This actually sounds kind of neat, particularly the pronunciation correction. It's not going to replace teachers, but could be nice for additional practice or for people self-studying without much opportunity for interaction and output.

I kind of want one...

Pre-Workshop HW

I encourage everyone to bring laptops to the workshop. This way, you can follow along and get more familiar with the R interface in a setting where you can ask questions and get help with the basics.


Of course, you'll need to have R and RStudio installed on your machine.


  1. Start by downloading and installing R here.
  2. Then, get RSTudio here (just get the free one, of course).

After you get things installed, open RStudio. You'll need to install 2 packages for the workshop: dplyr and tidyr. There are two ways to do this:


  1. In the bottom-right panel in RStudio, click the “Packages” tab. Then, click the “Install” button and type “dplry, tidyr” (no quotes), check “install dependencies”, and then click “Install”.

OR


  1. In the console panel (left side or bottom-left), enter the following code:

install.packages("dplyr", dependencies = TRUE)
install.packages("tidyr", dependencies = TRUE)

You might see a lot of red text flash across your screen, but that's (probably) nothing to worry about.


If you have any trouble getting your machine set up, let me know before the workshop and I'll see what I can do to help you out.


English Varieties in Star Wars side-story "Rogue One"

For a long time, English spoken by characters in fantasy and sci-fi movies has generally been American (e.g., Luke, Han, and Leia in the original Star Wars trilogy) or one of several British/Scottish varieties (from Obi-Wan Kenobi to the dwarves and elves in Lord of the Rings). In the world of linguistics, American and British English varieties are considered to be Inner Circle varieties: the dominant varieties with long histories, typically spoken by monolinguals or 'balanced' bilinguals from an early age (Kachru, 1985). Of course, there is little reason that would necessitate denizens of medieval fantasy worlds or intergalactic space travelers to speak English like Anderson Cooper or Benedict Cumberbatch, but hey, that's Hollywood. To me, that's what makes the creative choices in language so interesting in fantasy/sci-fi: it's much more of an arbitrary choice compared to say, a period drama or a biopic, which would require authenticity to a real-world context.

But the recent Star Wars side-story, Rogue One, has attracted some attention for featuring English colored by non-Inner Circle English varieties- and not just villains. Actor Diego Luna's Mexican roots are reflected in his portrayal of Cassian Andor (skip to about 1:19 to hear some Cassian lines):



As you can hear in the interview, Luna's Mexican English shines through his Cassian lines. However, before getting too excited about Mexican English as a full-blown variety being featured in the film, I would say it's mostly a Mexican accent that is featured. A full-blown variety of English would be marked by a set of distinct lexical and syntactic features in addition to phonology (pronunciation of particular sounds, intonation and stress patterns, etc.). You can hear a bit of a difference in Luna's interview, which was not scripted and rehearsed like movie lines are.

Donnie Yen's performance as blind temple guardian Chirrut Imwe piqued my linguistic attention, too. Yen is from Hong Kong (and a kung fu and action movie legend by the way), and Chirrut's lines reflect Yen's HK English. At this point, it's still difficult to track down Chirrut audio online, but I would be curious of any of Yen's distinct HK English features outside of pronunciation show up in the film, like plural marking that is quite different from standard American or British varieties (HK English plural marking is easily identifiable in Yen's interviews, e.g. "one of the main feature" at around 0:18 here: https://youtu.be/jyPdrKZ2grg).

So I don't know that new(er) English varieties have made their big splash in Hollywood yet, but this is still a cool thing that's happened with Rogue One.



The Brain and (Adult) Language Learning

Some interesting work has come out recently that examines brain activity and language learning, mostly in adults. This straddles conventional neurolinguistics/cognitive science and second language acquisition, and I think this is an important and hopefully productive area of inquiry. However, some of this work is very exploratory- or pioneering, to use more positive phrasing (which I think is deserved!).

A recent piece on the Scientific American website highlighted a couple recent studies, one of which I read a few months ago. The headline reads as follows:
Some People’s Brains Are Wired for Languages 
Brain scans may offer clues to a person’s natural aptitude—and help those less gifted learn how to study better
I found this title to go a bit too far, mainly because the studies reviewed do not necessarily speak to a specific language learning aptitude, and the operationalization and measurement of language learning in the studies is somewhat lacking.

For example, in the first study in the SA article (Qi et al., 2015), Mandarin learning was predicted by right hemisphere measures (basically, differences in the structure of white matter). Mandarin learning is based on a classroom Listening/Reading/Speaking test, a pinyin dictation task, and a vocabulary test. Few details were provided about the classroom test, other than that it was presented mostly in Mandarin (so Chinese characters?) and scored by the teacher. Part of me likes the inclusion of the classroom test, which brings in some communicative skills- it's also reflective of real-world language learning and outcomes that people care about. But often, teacher-made and scored classroom tests focus on discrete bits and highly-practiced materials- so studying the night before (or in the 10 minutes before class) could be just as influential on results as actual acquisition of linguistic forms and development of communicative competence. The dictation task required students to write 10 (yes, just ten) words/phrases in pinyin, a phonetic script with Latin letters. The obvious confound here is that pinyin knowledge could be confounded with Mandarin phonetic discrimination. The vocabulary test involved 30 words presented in English (how often were these words presented in the curriculum?) and a choice of two Chinese characters, one of which was a correct translation and the other a similar-looking character (imagine choosing between star and stare in English)- so, a 50% chance to get it right just by guessing. Scores for the latter two measures were percent correct. To some extent, the limited coverage of the learning measures understandably reflects the limited learning experience in the study (60ish hours of classroom learning). It could be that the brain measures relate to a general analytic capacity/phonetic discrimination capacity rather than language learning/aptitude for language learning, and the psychometric properties of the tests potentially introduce a fair amount of noise on top of that.

The second study (link here) French learning was predicted (substantially- 60% of variance explained) by resting EEG readings. French learning was operationalized by progress through an interactive/game-based French learning course (about 8 or so hours worth of study, from what I can tell). The course actually sounds really cool (for lack of a better word)- you have to carry out real-world-esque tasks in a virtual French immersion environment. But progress through a self-paced language course could be based as much on personality and general analytic/reasoning skills as an aptitude for SLA. In the SA article, one of the study authors admits as much, which was nice to see. In a Duolingo project I've worked on (as a participant-researcher), I outpaced a few colleagues in learning Turkish, but that alone doesn't mean I actually acquired more Turkish. The authors did get a bunch of general cognitive measures from the participants, none of which had significant correlations- which could be support for the resting EEG having a meaningful connection with language learning, or it could just be the case that not many correlations are going to be significant when you have 16 people.

Although I'm critical here, I do think there's a lot of potential in this work. I definitely think these authors are on to something, but I hope future work can clarify what that is- and on the language side, better-defined and operationalized measures of linguistic competence/communicative ability could be a great help.

"Arrival" is a really positive representation of linguistics and language learning

Arrival is a fantastic piece of science fiction. 12 (peaceful) alien spaceships arrive on earth, and a linguist is recruited to establish communication while the world at large slips into fear and panic. I will try to avoid spoilers here- go see it for yourself. But consider this a review of how the film portrays linguistics, linguists, and foreign language learning. I'll cover pros and cons:

PROS:
  • The complexity of language is presented with major importance to the plot. For example, Amy Adams' character has to explain how linguistically complicated the interrogative "What is your purpose on Earth?" to an Air Force general who sees it as one simple question composed of 6 words.
  • Linguistics is presented as science, and fights for equal standing along hard sciences. Jeremy Renner's character is a NSF scientist (chemist? physicist?) who is initially a bit dismissive of linguistics, making a distinction between language and science. But he is won over, and ends up being Adams' supporter. 
  • Interaction. Adams needs to interact directly with the aliens in order for there to be any way for her to learn their language/teach them ours. Interaction is key in language learning! 
  • Language teaching and learning is presented pretty positively. We get to see Adams' character providing comprehensible input to the aliens, using gestures and actions to illustrate concepts. She has to start with extremely simple messages, and gradually works up from there. Communication is important to the whole process.
  • Written language. The alien writing system is key for humans learning the language, and I think this is a nice parallel to the real world, where written language can provide a huge boon to foreign language learning, especially for adults. Some would argue that for adults in non-immersion contexts, it's really the ease of accessing a particular writing system that determines the difficulty of learning another language. The classic example is Mandarin being especially difficult for Anglophones, even though Mandarin is really no more or less complex than French (of course, cognate vocabulary also plays a role).
CONS:
  • Louise Banks (the linguist played by Amy Adams) speaks a lot of languages, and can interpret to English in real-time. While it's not a bad thing at all to have Anglophone movie characters demonstrate multilingual abilities, it nonetheless reinforces the popular conception of a linguist as someone who knows many languages.
  • Just about the only linguistic theory mentioned by name is Sapir-Whorf. This is actually somewhat of a key plot point, so I can forgive it on that account, but in the real world the idea that the language you speak shapes how you think and experience the world has been largely debunked. There are only very slight differences in processing information across languages, and these amount to arguably negligible differences when it comes to forming a worldview.
All in all, this is the movie you tell friends to watch if you want them to get a basic sense of what linguistics is- it's not perfect, but I think it's better than linguists-as-accent-coaches in My Fair Lady. It's also a well-crafted, entertaining movie otherwise. I think I'm going to have to check out director Denis Villeneuve's other work!

Communication Breakdown in Conversation: Pronunciation, Phonological Reception, Vocabulary... or a little bit of everything?

Alternate title: Dan overthinks a misunderstanding

As part of my ongoing efforts to at least retain, if not develop, my Korean abilities, I have been attending the Korean Conversation Table at my university (also, my wife helps put these on, so I kind of have to go- which is a good thing!).

I usually get grouped with a native speaker or two and some undergraduates who have finished all the Korean coursework and spent some time abroad, so we get some good conversation going on a range of topics. Generally, communication is doable, if a bit laborious at times, but occasionally someone experiences a breakdown, small or large.

At the most recent meeting, I experienced a major breakdown, but it was due to a really small bit that, once I realized my error, made me want to smack myself on the forehead. Another learner was talking about an internship she applied for, and she was worried that the working hours would be long- a topic I could generally follow along. In trying to explain her concerns about long working hours, she was talking about keeping a 9-5 schedule. In Korean, she was using the word 퇴근 (/twɛ.gɯn/), meaning "leaving work time", repeatedly (which makes sense). But for some reason, I kept hearing what I thought was something like 제근 (/dʑɛ.gɯn/)- a word that doesn't exist. It's worth mentioning that I think her pronunciation is quite clear (moreso than my own!), so I don't really know what was going on with my perception. I keyed on to the 근 morpheme, which I recognized as "work" and it was something that made sense given the context, so I started to think that "제근" was something like "regular work" (제 can mean something like "system" or "correct").

After sitting and listening, and spinning the gears in my head over what this word I thought I was hearing could mean, eventually I had to ask some clarification questions.  This helped me understand that she was actually saying 퇴근, a word I knew which makes total sense in this context (hence the smacking myself on the forehead). To indicate that I knew what she meant in relation to the topic, I offered the word 야근, which means "overtime"- a word that maybe I was expecting, given the topic, but she was unfamiliar with.

Meanwhile, the native speaker in the group naturally had no trouble following and helping both of us.

Fiction meets (near-)reality: Language Teaching and Technology

Instead of staring at my phone before going to bed, I've decided to buck the trend of "no for-pleasure reading in grad school." I'm currently reading Ready Player One by Ernest Cline. This is a book set in the near future where the virtually the whole planet regularly plugs in to a virtual reality called OASIS. OASIS is even used to deliver free public education, which includes language classes. A couple excerpts stood out to me:

Unfortunately, even with the limitless possibilities of OASIS at her disposal, my Latin teacher, Ms. Rank, still had a hard time making her lessons interesting. And today she was reviewing a bunch of verbs I'd already memorized, so I found my attention drifting almost immediately. (p. 61)
I think this is often the case in the present- impressive technology is used in very conventional and often boring ways. Sometimes convention works- I'm a big fan of digital vocabulary flashcards. But sometimes (more often than not?) putting a slick interface on top of low-engagement, low-context activities does very little to help language learning.

A few pages later, Cline describes the method of the protagonist's Latin teacher, Ms. Rank:
Our teacher, Ms. Rank, was standing at the front of the class, slowly conjugating Latin verbs. She said them in English first, then in Latin, and each word automatically appeared on the board behind her as she spoke it. Whenever we were doing tedious verb conjugation, I always got the lyrics to an old Schoolhouse Rock! song stuck in my head: "To run, to go, to give. Verb! You're what's happenin'!"

I was quietly humming this tune to myself when Ms. Rank began to conjugate the Latin for the verb "to learn." "To Learn. Discere," she said. "Now, this one should be easy to remember, because it's similar to the English word 'discern,' which also means 'to learn.'"

...

Ms. Rank continued, using the verb in a sentence. "We go to school to learn," she said. "Petimus scholam ut litteras discamus."
So first, I found it interesting that this is how Cline envisions or remembers language classes. To be fair, this is a description of a Latin class, which is (mostly) a dead language, in the real world and in Cline's fiction. Second, this sort of teaching still happens for living languages, and particularly in a lot of online language learning resources like Youtube video lessons or explicitly-oriented language learning apps. Explicit, L1-delivered instruction can definitely help people feel more comfortable about meanings and rules, and does arguably have some beneficial effect on learning, but it's clearly not the main driver of language learning. I hope that as the field of language teaching continues to move forward and more people learn in communicative classrooms, the next generation of authors will paint a different picture for us.

What I did this summer - Internship at CaMLA

I interned at CaMLA (Cambridge Michigan Language Assessments) in Ann Arbor, MI over the summer. They asked me to do a brief write-up of the experience, which you can read here:

http://cambridgemichigan.org/blog/2016/09/29/an-interns-words-dan-isbell/