class: center, middle, inverse, title-slide .title[ # Advanced quantitative data analysis ] .subtitle[ ## R basic II ] .author[ ### Mengni Chen ] .institute[ ### Department of Sociology, University of Copenhagen ] --- #Packages today - package used in this session - tidyverse - haven - janitor ```r #we have installed "tidyverse" and "haven" last week #now we need to install "janitor" install.packages("janitor") ``` ```r #let use use the two package library(tidyverse) #check packages embedded in the tidyverse: https://www.tidyverse.org/packages/ library(haven) # Read and handle SPSS, Stata & SAS data (no need to install) library(janitor) #to provide some basic tabulations ``` --- #Import data ```r # Create an object pairfam and assign the imported anchor1_50percent.dta to it pairfam <- read_dta("anchor1_50percent_Eng.dta") pairfam ``` ``` ## # A tibble: 6,201 × 1,458 ## id demodiff wave sample pid parentidk1 parentidk2 parentidk3 ## <dbl> <dbl+lbl> <dbl+l> <dbl+l> <dbl> <dbl+lbl> <dbl+lbl> <dbl+lbl> ## 1 267206000 0 [0 non-… 1 [1 2… 1 [1 p… NA NA NA NA ## 2 112963000 0 [0 non-… 1 [1 2… 1 [1 p… NA NA NA NA ## 3 327937000 0 [0 non-… 1 [1 2… 1 [1 p… 3.28e8 NA NA NA ## 4 318656000 0 [0 non-… 1 [1 2… 1 [1 p… 3.19e8 318656101 NA NA ## 5 717889000 0 [0 non-… 1 [1 2… 1 [1 p… 7.18e8 717889101 717889101 NA ## 6 222517000 0 [0 non-… 1 [1 2… 1 [1 p… NA NA NA NA ## 7 144712000 0 [0 non-… 1 [1 2… 1 [1 p… NA NA NA NA ## 8 659357000 0 [0 non-… 1 [1 2… 1 [1 p… 6.59e8 NA NA NA ## 9 506367000 0 [0 non-… 1 [1 2… 1 [1 p… 5.06e8 506367101 NA NA ## 10 64044000 0 [0 non-… 1 [1 2… 1 [1 p… NA NA NA NA ## # ℹ 6,191 more rows ## # ℹ 1,450 more variables: parentidk4 <dbl+lbl>, parentidk5 <dbl+lbl>, ## # parentidk6 <dbl+lbl>, parentidk7 <dbl+lbl>, parentidk8 <dbl+lbl>, ## # parentidk9 <dbl+lbl>, parentidk10 <dbl+lbl>, parentidk11 <dbl+lbl>, ## # parentidk12 <dbl+lbl>, parentidk13 <dbl+lbl>, parentidk14 <dbl+lbl>, ## # parentidk15 <dbl+lbl>, sex_gen <dbl+lbl>, psex_gen <dbl+lbl>, ## # k1sex_gen <dbl+lbl>, k2sex_gen <dbl+lbl>, k3sex_gen <dbl+lbl>, … ``` --- #Address single variable using **$** -- ```r # use $ to locate variable "age" pairfam$age #return the variable ``` -- ```r # Give a summary of numeric vector age contained in Dat. summary(pairfam$age) ``` ``` ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 14.00 17.00 26.00 25.84 35.00 38.00 ``` --- #Address single variable using **$** ```r # summarise a factor vector,i.e. a categorical variable sex_gen(variable name for gender). summary(pairfam$sex_gen) ``` ``` ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 1.000 1.000 2.000 1.512 2.000 2.000 ``` ```r table(pairfam$sex_gen) ``` ``` ## ## 1 2 ## 3029 3172 ``` -- why R seems to treat sex_gen(var for gender) like a continuous variable? because it saves a lot space to store information in numbers. --- #Address single variable using **$** make sure that you treat categorical variables as factor in R ```r pairfam$gender <- as_factor(pairfam$sex_gen)# make it as a factor tabyl(pairfam$gender) #or you can use table() ``` ``` ## pairfam$gender n percent ## -10 not in demodiff 0 0.0000000 ## -7 Incomplete data 0 0.0000000 ## -4 Filter error / Incorrect entry 0 0.0000000 ## -3 Does not apply 0 0.0000000 ## 1 Male 3029 0.4884696 ## 2 Female 3172 0.5115304 ``` --- #Selection in R: 3 situations - Situation 1: selecting variables, using `select()` - Situation 2: build a subset of data based on values of certain variables, using `filter()` - Situation 1+2: using `[,]` - Situation 3: generate or recode variables based on certain conditions, using `case_when()` --- #Situation 1: use `select()` to select several variables Select three variables to make a small dataset ```r #select(dataset, var1, var2, var3,etc.) pairfam1 <- select(pairfam, id, age, gender) pairfam1 ``` ``` ## # A tibble: 6,201 × 3 ## id age gender ## <dbl> <dbl+lbl> <fct> ## 1 267206000 16 2 Female ## 2 112963000 35 1 Male ## 3 327937000 16 2 Female ## 4 318656000 27 2 Female ## 5 717889000 37 1 Male ## 6 222517000 15 1 Male ## 7 144712000 16 2 Female ## 8 659357000 17 2 Female ## 9 506367000 37 1 Male ## 10 64044000 15 2 Female ## # ℹ 6,191 more rows ``` --- #`select()` to drop several variables -- .pull-left[ drop variable age ```r # remove gender pairfam2 <- select(pairfam1, -gender) pairfam2 ``` ``` ## # A tibble: 6,201 × 2 ## id age ## <dbl> <dbl+lbl> ## 1 267206000 16 ## 2 112963000 35 ## 3 327937000 16 ## 4 318656000 27 ## 5 717889000 37 ## 6 222517000 15 ## 7 144712000 16 ## 8 659357000 17 ## 9 506367000 37 ## 10 64044000 15 ## # ℹ 6,191 more rows ``` ] .pull-right[ if you have more variables to drop ```r # drop age and id (pairfam3 <- select(pairfam1, -c(id,age))) ``` ``` ## # A tibble: 6,201 × 1 ## gender ## <fct> ## 1 2 Female ## 2 1 Male ## 3 2 Female ## 4 2 Female ## 5 1 Male ## 6 1 Male ## 7 2 Female ## 8 2 Female ## 9 1 Male ## 10 2 Female ## # ℹ 6,191 more rows ``` ] --- # Situation 2: use `filter()` to select observations based on values in certain variables ```r #filter(dataset, condition1 & condition2) data_above30<- filter(pairfam1, age>30) #keep respondents whose age is >30. data_above30 ``` ``` ## # A tibble: 2,015 × 3 ## id age gender ## <dbl> <dbl+lbl> <fct> ## 1 112963000 35 1 Male ## 2 717889000 37 1 Male ## 3 506367000 37 1 Male ## 4 408364000 36 1 Male ## 5 597606000 36 1 Male ## 6 505725000 38 2 Female ## 7 19046000 35 2 Female ## 8 84655000 36 2 Female ## 9 36945000 35 2 Female ## 10 690012000 37 1 Male ## # ℹ 2,005 more rows ``` --- # Situation 2: use `filter()` to select observations based on values in certain variables ```r levels(pairfam1$gender)#check how female is coded,"2 Female" ``` ``` ## [1] "-10 not in demodiff" "-7 Incomplete data" ## [3] "-4 Filter error / Incorrect entry" "-3 Does not apply" ## [5] "1 Male" "2 Female" ``` ```r data_female<- filter(pairfam1, gender=="2 Female") data_female ``` ``` ## # A tibble: 3,172 × 3 ## id age gender ## <dbl> <dbl+lbl> <fct> ## 1 267206000 16 2 Female ## 2 327937000 16 2 Female ## 3 318656000 27 2 Female ## 4 144712000 16 2 Female ## 5 659357000 17 2 Female ## 6 64044000 15 2 Female ## 7 252002000 25 2 Female ## 8 215305000 17 2 Female ## 9 107033000 17 2 Female ## 10 505725000 38 2 Female ## # ℹ 3,162 more rows ``` --- #Situation 1+2: using `[]` ```r name <- c("Agnes", "Martin", "Hakan", "Tu", "Thais") age <- c(34, 22, 42, 12, 76) conti <- factor(x = c("Europe", "Africa", "Africa", "Asia", "S. America"), levels = c("Africa", "Asia", "Australia", "Europe", "N. America", "S. America")) employed <- c(FALSE, TRUE, TRUE, TRUE, TRUE) example <- data.frame(name,age,conti, employed) example <- as_tibble(example)#a more user-friendly way of showing data example ``` ``` ## # A tibble: 5 × 4 ## name age conti employed ## <chr> <dbl> <fct> <lgl> ## 1 Agnes 34 Europe FALSE ## 2 Martin 22 Africa TRUE ## 3 Hakan 42 Africa TRUE ## 4 Tu 12 Asia TRUE ## 5 Thais 76 S. America TRUE ``` --- #Situation 1+2: using `[,]` .pull-left[ ```r example ``` ``` ## # A tibble: 5 × 4 ## name age conti employed ## <chr> <dbl> <fct> <lgl> ## 1 Agnes 34 Europe FALSE ## 2 Martin 22 Africa TRUE ## 3 Hakan 42 Africa TRUE ## 4 Tu 12 Asia TRUE ## 5 Thais 76 S. America TRUE ``` ```r (example1 <- example[1, 3]) ``` ``` ## # A tibble: 1 × 1 ## conti ## <fct> ## 1 Europe ``` ] .pull-right[ ```r # Or use the index, to achieve the same. (example2 <- example[1, ]) ``` ``` ## # A tibble: 1 × 4 ## name age conti employed ## <chr> <dbl> <fct> <lgl> ## 1 Agnes 34 Europe FALSE ``` ```r (example3 <- example[, 3]) ``` ``` ## # A tibble: 5 × 1 ## conti ## <fct> ## 1 Europe ## 2 Africa ## 3 Africa ## 4 Asia ## 5 S. America ``` ] --- #Situation 1+2: using `[rows, column]` ```r #select variables (example4 <- example[, c("age","conti")]) # [,"the column name to select"] ``` ``` ## # A tibble: 5 × 2 ## age conti ## <dbl> <fct> ## 1 34 Europe ## 2 22 Africa ## 3 42 Africa ## 4 12 Asia ## 5 76 S. America ``` -- ```r #select observations based on values of certain variables (example5 <- example[age>40, ]) ``` ``` ## # A tibble: 2 × 4 ## name age conti employed ## <chr> <dbl> <fct> <lgl> ## 1 Hakan 42 Africa TRUE ## 2 Thais 76 S. America TRUE ``` --- #Situation 1+2: using `[,]` use `[conditions,"var name"]` to select ```r example ``` ``` ## # A tibble: 5 × 4 ## name age conti employed ## <chr> <dbl> <fct> <lgl> ## 1 Agnes 34 Europe FALSE ## 2 Martin 22 Africa TRUE ## 3 Hakan 42 Africa TRUE ## 4 Tu 12 Asia TRUE ## 5 Thais 76 S. America TRUE ``` ```r (example6 <- example[age>40,c("age","conti")])#keep those aged>40 but only select two vars. ``` ``` ## # A tibble: 2 × 2 ## age conti ## <dbl> <fct> ## 1 42 Africa ## 2 76 S. America ``` --- #Generate or recode variables To transform and recode simply use `$` to clarify which var from which dataset you are referring to. ```r # Center age around the average age. example$age_centered <- example$age - mean(example$age) # Recode "Africa" to "Afrika!". example$conti1 <- fct_recode(example$conti, "Afrika!" = "Africa") example ``` ``` ## # A tibble: 5 × 6 ## name age conti employed age_centered conti1 ## <chr> <dbl> <fct> <lgl> <dbl> <fct> ## 1 Agnes 34 Europe FALSE -3.20 Europe ## 2 Martin 22 Africa TRUE -15.2 Afrika! ## 3 Hakan 42 Africa TRUE 4.8 Afrika! ## 4 Tu 12 Asia TRUE -25.2 Asia ## 5 Thais 76 S. America TRUE 38.8 S. America ``` --- #Generate or recode variables If you want to transform and recode several variables at the same time, you can use `mutate()`. ```r example_new1 <- mutate( example, # Use the data "example". age_z = age_centered / sd(age), # z-standardize age. conti2= fct_recode(conti, # recode gender to gender2 "Europa!" = "Europe", # "Europe" to "Europa!". "Asien!" = "Asia") # "Asia" to "Asien!". ) # Don't forget to close mutate's bracket ")" example_new1 ``` ``` ## # A tibble: 5 × 8 ## name age conti employed age_centered conti1 age_z conti2 ## <chr> <dbl> <fct> <lgl> <dbl> <fct> <dbl> <fct> ## 1 Agnes 34 Europe FALSE -3.20 Europe -0.131 Europa! ## 2 Martin 22 Africa TRUE -15.2 Afrika! -0.620 Africa ## 3 Hakan 42 Africa TRUE 4.8 Afrika! 0.196 Africa ## 4 Tu 12 Asia TRUE -25.2 Asia -1.03 Asien! ## 5 Thais 76 S. America TRUE 38.8 S. America 1.58 S. America ``` <span style="color:red;">**Attention: look how RStudio structures the brackets!** --- #Situation 3: generate or modify variables based on certain conditions To transform/recode only among certain cases, use `case_when()`. ```r example_new2 <- mutate( example, # Mutate variables contained in example data. work=NA,#create var work and make it missing in the begining work = case_when( # Start conditional recode of work, employed == FALSE ~ "not working", # 1. your condition ~ new value "not working" , employed == TRUE ~ "working" # 2. your condition ~ new value "working", ) # close case_when's bracket. ) example_new2 ``` ``` ## # A tibble: 5 × 7 ## name age conti employed age_centered conti1 work ## <chr> <dbl> <fct> <lgl> <dbl> <fct> <chr> ## 1 Agnes 34 Europe FALSE -3.20 Europe not working ## 2 Martin 22 Africa TRUE -15.2 Afrika! working ## 3 Hakan 42 Africa TRUE 4.8 Afrika! working ## 4 Tu 12 Asia TRUE -25.2 Asia working ## 5 Thais 76 S. America TRUE 38.8 S. America working ``` --- #Situation 3: generate or modify variables based on certain conditions To transform/recode only among certain cases, use `case_when()`. ```r example_new3 <- mutate(example, # dataset conti = case_when( # Start conditional recode of conti, employed == FALSE ~ "Atlantis", # 1. complex condition ~ new value "Atlantis", age < 25 & employed == TRUE ~ "Antarctica") # 2. complex condition ~ new value "Antarctica" ) example_new3 ``` ``` ## # A tibble: 5 × 6 ## name age conti employed age_centered conti1 ## <chr> <dbl> <chr> <lgl> <dbl> <fct> ## 1 Agnes 34 Atlantis FALSE -3.20 Europe ## 2 Martin 22 Antarctica TRUE -15.2 Afrika! ## 3 Hakan 42 <NA> TRUE 4.8 Afrika! ## 4 Tu 12 Antarctica TRUE -25.2 Asia ## 5 Thais 76 <NA> TRUE 38.8 S. America ``` **Why "conti" becomes a character variable?** **Why "conti" have 2 missing values "NA"?** --- ##Conditional transform & recode Let us compare the following with the previous slide ```r example_new3 <- mutate(example, # dataset conti = case_when( # Start conditional recode of conti, employed == FALSE ~ "Atlantis", # 1. complex condition ~ new value "Atlantis", age < 25 & employed == TRUE ~ "Antarctica", # 2. complex condition ~ new value "Antarctica", TRUE ~ as.character(conti)) # close case_when's bracket. ) example_new3 ``` ``` ## # A tibble: 5 × 6 ## name age conti employed age_centered conti1 ## <chr> <dbl> <chr> <lgl> <dbl> <fct> ## 1 Agnes 34 Atlantis FALSE -3.20 Europe ## 2 Martin 22 Antarctica TRUE -15.2 Afrika! ## 3 Hakan 42 Africa TRUE 4.8 Afrika! ## 4 Tu 12 Antarctica TRUE -25.2 Asia ## 5 Thais 76 S. America TRUE 38.8 S. America ``` --- #Conditional transform & recode Let us see what the three lines of code in `case_when()` do 1. For all non-employed ~ recode conti to "Atlantis". 2. For all those who're aged< 25 and employed ~ recode conti to "Antarctica". 3. All remaining cases ~ use their original conti values, but transform them to a character vector. Remember, R is class sensitive! It will not combine numeric information into a character vector. Because we give case_when() "Atlantis" and "Antarctica" as new values, it assumes that we want to make conti a character vector. ```r example_new3 <- mutate( example, # Mutate variables contained in Dat. conti = case_when( # Start conditional recode of conti, employed == FALSE ~ "Atlantis", # 1. complex condition ~ new value "Atlantis", age < 25 & employed == TRUE ~ "Antarctica", # 2. complex condition ~ new value "Antarctica", TRUE ~ as.character(conti) ) # close case_when's bracket. ) ``` --- #A task to do with pairfam data now? Task: - 1) Construct a new dataset "small_pf" only containing variables: id, age, sex_gen, cohort, sat6; - 2) Create gender and cohort_group variables as factors to represent sex_gen and cohort as categorical. - 3) Create a new variable called sat_missing: when sat6 is valid answer, use the original value; when sat6 is negative make it NA Note: sat6 asks the general life satisfaction (0=very unsatisfied, 10=very satisfied) How will you handle this task? What kind of codes will you use? --- #A task to do with pairfam data now? What we can do: ```r #Step1: import data pairfam <- read_dta("anchor1_50percent_Eng.dta") #Step2: select variables and create a dataset named small_pf using select() small_pf <- select(pairfam, id, age, sex_gen, cohort, sat6) #select chozen variables #Step3: treat categorical variables as factor small_pf1 <- mutate(small_pf, gender=as_factor(sex_gen),#make gender as a factor cohort_group=as_factor(cohort) #make cohort_group as a factor ) #Step4: create sat_missing small_pf2<- mutate(small_pf1, sat_missing=case_when( sat6<0 ~ NA, #replace sat6 with NA when sat6<0 TRUE ~ sat6) ) ``` --- #Is there any more efficient way to do? Use pipe `%>%` - If we do the task step by step as the previous slide shows, you will create 3 dataset as intermediate dataset. - But, we can use pipe `%>%` to make it more efficient. - The `%>%` operator pipes output of one function as input to the next function. You can basically say: `function(argument1 = value)` can be written as `value %>% function()`. Or even easier, think of it as: "then" ```r mean(sqrt(seq(from = 1, to = 13))) ``` ``` ## [1] 2.527274 ``` ```r #use pipe seq(from = 1, to = 13) %>% sqrt() %>% mean() ``` ``` ## [1] 2.527274 ``` --- #The (forward) pipe ` %>% ` - Shortcut buttons for typing `%>%`: Windows: Ctrl+Shift+M; Mac: Cmd+Shift+M ```r # Example 1: round(x=., digits =.) #Both lines of code round 5.882 to have only one digit. round(x = 5.882, digits = 1) ``` ``` ## [1] 5.9 ``` ```r 5.882 %>% round(digits = 1) ``` ``` ## [1] 5.9 ``` ```r #Example 2 2 %>% round(x = 5.882, digits = .) ``` ``` ## [1] 5.88 ``` By default, %>% pipes into the first argument of a function. The . placeholder allows us to pipe into another argument. --- # What pipe looks like? .pull-left[ <img src="https://merlin-intro-r.netlify.app/5-piping/img/PipedEgg.jpg" width="190%" style="display: block; margin: auto;" > ] .pull-right[ <img src="https://merlin-intro-r.netlify.app/5-piping/img/PipedEgg2.png" width="690%" style="display: block; margin: auto;"> ] --- #Advantages of piping & when not to pipe - The advantages are - Legible code: We can structure code from left to right, as opposed to from inside and out. - Shorter code: You minimize the need for local/intermediate variables. - Easily mutable code: You can easily add steps anywhere in the sequence of operations. - When not to pipe - If you have more than one or two major inputs, don't pipe. - If you have more than ten steps, better make intermediate object. It helps you to debug (i.e., find mistakes) and is simply easier to read. [Example video](https://www.youtube.com/watch?v=sohARFx6aTo) --- #Use pipe `%>%` to do the task But now: way 2 using ` %>%` ```r #Step1: import data pairfam <- read_dta("anchor1_50percent_Eng.dta") #Step2: to make it all done small_pf <- pairfam %>% select(id, age, sex_gen, cohort, sat6) %>% mutate(gender=as_factor(sex_gen), #make gender as a factor; cohort_group=as_factor(cohort), #make cohort_group as a factor; sat_missing=case_when( sat6<0 ~ NA, #replace sat6 with NA when sat6<0 TRUE ~ sat6) ) ``` --- #Use pipe `%>%` and `transmute()` to do the task - Oooh, what is `transmute()`? ```r #compare data1 and data2 data1 <- mutate(pairfam, gender=as_factor(sex_gen), #make gender as a factor; cohort_group=as_factor(cohort) #make cohort_group as a factor; ) data2 <- transmute(pairfam, gender=as_factor(sex_gen), #make gender as a factor; cohort_group=as_factor(cohort) #make cohort_group as a factor; ) ``` `transmute()` only keep variables you specify in the `transmute()` [Difference between `mutate()` and `transmute()`](https://www.youtube.com/watch?v=vvIhRginelA) --- #Use pipe `%>%` and `transmute()` to do the task But now: way 3 using ` %>%` and `transmute()` ```r #Step1: import data pairfam <- read_dta("anchor1_50percent_Eng.dta") #Step2: to make it all done small_pf <- pairfam %>% transmute(id, age, sex_gen, cohort, sat6, gender=as_factor(sex_gen), #make sex_gen as a factor, named gender cohort_group=as_factor(cohort), #make cohort as a factor, named cohort_group sat_missing=case_when( sat6<0 ~ NA, #replace sat6 with NA when sat6<0 TRUE ~ sat6) ) ``` --- #Try another task using `%>%` Task: generate a nice two-way table on cohort_group and gender ```r tabyl(small_pf, cohort_group, gender)#tabyl(dataset, var1, var2) ``` ``` ## cohort_group -10 not in demodiff -7 Incomplete data ## -7 Incomplete data 0 0 ## 0 former capikid first interview 0 0 ## 1 1991-1993 0 0 ## 2 1981-1983 0 0 ## 3 1971-1973 0 0 ## 4 2001-2003 0 0 ## 9 former capikid re-interview 0 0 ## -4 Filter error / Incorrect entry -3 Does not apply 1 Male 2 Female ## 0 0 0 0 ## 0 0 0 0 ## 0 0 1112 1061 ## 0 0 1000 1013 ## 0 0 917 1098 ## 0 0 0 0 ## 0 0 0 0 ``` oooh, no! Not really can be said "nice"! --- #Try another task using `%>%` .pull-left[ ```r small_pf %>% mutate( gender=fct_drop(gender), cohort_group=fct_drop(cohort_group) )%>% tabyl(cohort_group, gender) ``` ``` ## cohort_group 1 Male 2 Female ## 1 1991-1993 1112 1061 ## 2 1981-1983 1000 1013 ## 3 1971-1973 917 1098 ``` ] .pull-right[ ```r small_pf %>% mutate(gender=fct_drop(gender), cohort_group=fct_drop(cohort_group))%>% tabyl(cohort_group, gender)%>% adorn_totals("row") %>% #add row total adorn_percentages("row") %>% #add row % adorn_pct_formatting() %>% #format the percentage adorn_ns(position="front")%>% #add absolute n in front adorn_title() %>% #add title knitr::kable() #generate a table ``` | |gender | | |:------------|:-------------|:-------------| |cohort_group |1 Male |2 Female | |1 1991-1993 |1,112 (51.2%) |1,061 (48.8%) | |2 1981-1983 |1,000 (49.7%) |1,013 (50.3%) | |3 1971-1973 |917 (45.5%) |1,098 (54.5%) | |Total |3,029 (48.8%) |3,172 (51.2%) | ] --- #Take home 1. The function of `$` for identifying a variable in a dataset 2. Three situations of selection in R - select() to select several variables - filter() to select observations based on values in certain variables - [] can also be used for select both variables and observations - case_when() to recode or create variables based on conditions 4. Use pipe ` %>% ` to make coding more efficient --- # Important code - as_tibble(): take a data frame and make it a Tibble. - summary(): Give a summary of an object. - select(): select several variables from a data frame/Tibble. - filter(): filter cases based on values in certain variables. - case_when(): Conditional recode for cases filtered in complex ways. - mutate(): Adds new variables and preserves existing. Good for recoding several variables. - transmute(): similar to mutate but only keep variables you specify in the () - as_factor(): Make a labelled Stata/SPSS variable a factor. - tabyl(): Make a two-way table --- class: center, middle #[Exercise](https://rpubs.com/fancycmn/1343533)