Loop over columns to generate multiple prop.table

Dear All,
I have a survey data set and would like to disaggregate all content variables (79 vars on a likert scale) by several categorical variables (here I give the example of component_new).
Obviously, I can't copy and paste each variable individually.

So my question is how I can reproduce this code snipped for all Var_content columns.

tab <- round(prop.table(table(component_new, Var_content), margin = 1),2 )
ftable(tab)

Now, I would like to write a for loop over the columns but dont understand how I can use the indices.
My first column in the variable I'd like to disaggregate:
here the glimpse:

Observations: 6,166
Variables: 79
component_new <chr> "Military", "Unknown", "Civilian-IS", "Civilian-IS", "Civilian-IS",… Mysupervisor_x 5, NA, 5, 4, 4, 5, NA, 1, 5, 5, 4, 1, 4, 4, 4, 4, 2, 4, 5, 5, 4, NA…
$ Mysupervisor_x 5, NA, 5, 4, 5, 5, NA, 1, 5, 5, 5, 2, 3, 4,

I unsuccessfully tried this:

By_ comp <- for (i in Var_cont) {
prop.comp <- round(prop.table(table(component_new, Var_cont[i]), margin = 1),2 ) %>%
ftable(prop.comp )
}

Also unsuccessful was to use an index in the form of:
for (i in Var_cont[,2:79]) {...}

or

Var_cont %>% for (i in [,2:79]) {...}

or

for(i in 2:ncol(Vars_cont)) {...}

the last option
for(i in 2:ncol(Vars_cont)) {
tab <- table(Vars_cont$component_new, Vars_cont[,i])
prop <- prop.table(tab, margin = 1)
print(prop)
}
Gives me the error message "Error in table(Vars_cont$component_new, Vars_cont[, i]) : all arguments must have the same length".
The other attempt dont even get an error message :slight_smile:

Thank you very much and sorry for the terrible code!

Martin

This really cries out for a reproducible example, called a reprex with a handful of representative rows and columns or a data set from a package that has the same general layout.

Second, disaggregate isn't clear. Are you trying to break up into groups of columns? Are you trying to do something with each column?

It may be possible to figure this out by reverse engineering but few peeps are going to put in that level of effort :grin:

Dear Technocrat,
Thanks for your help.

I tried the repex, but I dont understand it. I am sorry!

I have several variables I need to disaggregate by, they are all categorical variables. In the example it's component_new.

I dont want to break up groups, but rather get the percentage for the likert-scale by category (e.g. from component_new).

My problem is that I need to

  1. Loop over columns (not rows)
  2. Need to exclude the first column (since its the variable I disaggregate my data by).

My end product would be a table with
Likert scale item (1-5)
component_new. 1. 2. 3. 4. 5
Military. 10%. 10%50% 20% 10%
Civilian. 30%. 10%30% 20% 10%
Police. 20%. 10% 40% 20% 10%

Because I have so many variables, I would like to loop it across all columns, minus the one I disaggregate by (component_new)

I totally understand that it's annoying without a repex.
Thanks for the effort!

1 Like

OK, that's a start. Here's what a reprex would look like

library(likert)
#> Loading required package: ggplot2
#> Loading required package: xtable
# from the help example
data(pisaitems)
head(pisaitems)
#>          CNT           ST24Q01           ST24Q02           ST24Q03
#> 68038 Canada          Disagree    Strongly agree    Strongly agree
#> 68039 Canada             Agree Strongly disagree Strongly disagree
#> 68040 Canada    Strongly agree Strongly disagree Strongly disagree
#> 68041 Canada          Disagree          Disagree             Agree
#> 68042 Canada Strongly disagree          Disagree Strongly disagree
#> 68043 Canada             Agree Strongly disagree Strongly disagree
#>                 ST24Q04           ST24Q05           ST24Q06           ST24Q07
#> 68038 Strongly disagree    Strongly agree Strongly disagree             Agree
#> 68039    Strongly agree Strongly disagree             Agree Strongly disagree
#> 68040             Agree Strongly disagree    Strongly agree Strongly disagree
#> 68041 Strongly disagree          Disagree          Disagree             Agree
#> 68042          Disagree Strongly disagree          Disagree          Disagree
#> 68043             Agree Strongly disagree             Agree Strongly disagree
#>                 ST24Q08           ST24Q09           ST24Q10           ST24Q11
#> 68038          Disagree Strongly disagree             Agree             Agree
#> 68039             Agree    Strongly agree Strongly disagree Strongly disagree
#> 68040             Agree          Disagree          Disagree Strongly disagree
#> 68041 Strongly disagree Strongly disagree             Agree             Agree
#> 68042             Agree             Agree             Agree Strongly disagree
#> 68043             Agree    Strongly agree Strongly disagree Strongly disagree
#>                     ST25Q01               ST25Q02               ST25Q03
#> 68038    A few times a year  Several times a week Several times a month
#> 68039    About once a month    A few times a year Never or almost never
#> 68040    About once a month Never or almost never    A few times a year
#> 68041 Several times a month    A few times a year    About once a month
#> 68042    About once a month    A few times a year    About once a month
#> 68043    A few times a year Never or almost never Never or almost never
#>                     ST25Q04               ST25Q05               ST26Q01
#> 68038    A few times a year    A few times a year  Several times a week
#> 68039 Never or almost never  Several times a week  Several times a week
#> 68040 Never or almost never    A few times a year Never or almost never
#> 68041    A few times a year  Several times a week  Several times a week
#> 68042 Never or almost never Several times a month Several times a month
#> 68043 Never or almost never    A few times a year  Several times a week
#>                     ST26Q02               ST26Q03               ST26Q04
#> 68038  Several times a week Several times a month  Several times a week
#> 68039  Several times a week Several times a month Never or almost never
#> 68040  Several times a week  Several times a week Several times a month
#> 68041   Several times a day Several times a month Several times a month
#> 68042 Never or almost never Never or almost never Never or almost never
#> 68043   Several times a day Several times a month Several times a month
#>                     ST26Q05               ST26Q06               ST26Q07
#> 68038  Several times a week   Several times a day  Several times a week
#> 68039 Several times a month Don’t know what it is Several times a month
#> 68040 Several times a month Don’t know what it is Never or almost never
#> 68041  Several times a week Never or almost never  Several times a week
#> 68042 Never or almost never Never or almost never Never or almost never
#> 68043 Several times a month Never or almost never Several times a month
#>             ST27Q01       ST27Q02       ST27Q03      ST27Q04       ST27Q05
#> 68038         Often         Often         Often        Often         Often
#> 68039     Sometimes         Often         Often    Sometimes     Sometimes
#> 68040 Almost always Almost always Almost always    Sometimes Almost always
#> 68041         Often Almost always Almost always        Often     Sometimes
#> 68042         Often     Sometimes         Often    Sometimes Almost always
#> 68043     Sometimes         Often  Almost Never Almost Never  Almost Never
#>             ST27Q06   ST27Q07      ST27Q08       ST27Q09       ST27Q10
#> 68038         Often     Often        Often         Often         Often
#> 68039 Almost always     Often        Often Almost always Almost always
#> 68040     Sometimes     Often    Sometimes         Often     Sometimes
#> 68041 Almost always Sometimes Almost Never         Often  Almost Never
#> 68042     Sometimes Sometimes    Sometimes     Sometimes         Often
#> 68043         Often Sometimes Almost Never         Often  Almost Never
#>             ST27Q11      ST27Q12   ST27Q13      ST34Q01      ST34Q02
#> 68038         Often        Often     Often Strong agree Strong agree
#> 68039 Almost always    Sometimes     Often        Agree        Agree
#> 68040 Almost always    Sometimes     Often        Agree        Agree
#> 68041 Almost always    Sometimes     Often        Agree     Disagree
#> 68042         Often    Sometimes Sometimes        Agree        Agree
#> 68043 Almost always Almost Never     Often        Agree        Agree
#>            ST34Q03      ST34Q04      ST34Q05              ST36Q01      ST36Q02
#> 68038 Strong agree Strong agree Strong agree Never or hardly ever Some lessons
#> 68039        Agree        Agree        Agree Never or hardly ever Some lessons
#> 68040        Agree        Agree        Agree         Some lessons Most lessons
#> 68041        Agree Strong agree        Agree         Some lessons Most lessons
#> 68042        Agree        Agree        Agree         Most lessons Most lessons
#> 68043        Agree        Agree        Agree Never or hardly ever Some lessons
#>                    ST36Q03              ST36Q04              ST36Q05
#> 68038         Some lessons Never or hardly ever         Most lessons
#> 68039         Some lessons         Some lessons Never or hardly ever
#> 68040         Some lessons         Some lessons         Some lessons
#> 68041         Some lessons Never or hardly ever Never or hardly ever
#> 68042         Most lessons         Some lessons         Most lessons
#> 68043 Never or hardly ever Never or hardly ever Never or hardly ever
#>                    ST37Q01              ST37Q02              ST37Q03
#> 68038         Some lessons         Some lessons         Most lessons
#> 68039          All Lessons         Most lessons         Most lessons
#> 68040         Some lessons         Some lessons         Some lessons
#> 68041         Most lessons         Most lessons         Some lessons
#> 68042 Never or hardly ever Never or hardly ever Never or hardly ever
#> 68043         Some lessons         Some lessons         Most lessons
#>                    ST37Q04      ST37Q05              ST37Q06
#> 68038         Most lessons Most lessons          All Lessons
#> 68039         Most lessons  All Lessons         Some lessons
#> 68040         Some lessons Most lessons         Some lessons
#> 68041          All Lessons Most lessons         Some lessons
#> 68042         Some lessons Some lessons         Some lessons
#> 68043 Never or hardly ever Some lessons Never or hardly ever
#>                    ST37Q07      ST38Q01              ST38Q02      ST38Q03
#> 68038         Most lessons Some lessons         Most lessons  All Lessons
#> 68039          All Lessons Most lessons          All Lessons Most lessons
#> 68040         Some lessons Some lessons         Most lessons Some lessons
#> 68041 Never or hardly ever Most lessons         Most lessons  All Lessons
#> 68042         Some lessons Some lessons Never or hardly ever Some lessons
#> 68043 Never or hardly ever Most lessons         Most lessons Most lessons
#>            ST38Q04      ST38Q05              ST38Q06      ST38Q07      ST38Q08
#> 68038  All Lessons  All Lessons          All Lessons  All Lessons  All Lessons
#> 68039  All Lessons  All Lessons         Most lessons  All Lessons Most lessons
#> 68040 Most lessons Most lessons         Most lessons Most lessons Most lessons
#> 68041  All Lessons  All Lessons          All Lessons Most lessons Most lessons
#> 68042 Most lessons Some lessons Never or hardly ever Most lessons Some lessons
#> 68043 Most lessons  All Lessons         Some lessons Most lessons Some lessons
#>                    ST38Q09              ST39Q01            ST39Q02
#> 68038         Most lessons Several times a week A few times a year
#> 68039          All Lessons                Never              Never
#> 68040         Some lessons                Never A few times a year
#> 68041         Some lessons   A few times a year A few times a year
#> 68042 Never or hardly ever   A few times a year A few times a year
#> 68043         Some lessons                Never              Never
#>                     ST39Q03            ST39Q04              ST39Q05
#> 68038 Several times a month A few times a year Several times a week
#> 68039                 Never              Never                Never
#> 68040    About once a month              Never                Never
#> 68041    A few times a year A few times a year                Never
#> 68042    A few times a year              Never   A few times a year
#> 68043    A few times a year              Never                Never
#>                  ST39Q06              ST39Q07               ST41Q01
#> 68038 About once a month Several times a week       (6) Very Useful
#> 68039              Never                Never (1) Not useful at all
#> 68040 About once a month   About once a month                   (4)
#> 68041              Never                Never (1) Not useful at all
#> 68042 A few times a year                Never                   (3)
#> 68043              Never   About once a month                   (2)
#>                     ST41Q02               ST41Q03         ST41Q04
#> 68038       (6) Very Useful       (6) Very Useful (6) Very Useful
#> 68039                   (2)                   (3)             (4)
#> 68040                   (2)                   (3)             (3)
#> 68041 (1) Not useful at all                   (5) (6) Very Useful
#> 68042                   (3) (1) Not useful at all             (3)
#> 68043                   (3)                   (4) (6) Very Useful
#>               ST41Q05               ST41Q06         ST42Q01
#> 68038 (6) Very Useful       (6) Very Useful             (5)
#> 68039             (5)                   (4) (6) Very Useful
#> 68040             (2) (1) Not useful at all             (2)
#> 68041             (5)                   (2)             (4)
#> 68042             (2) (1) Not useful at all             (4)
#> 68043             (4)                   (5)             (3)
#>                     ST42Q02               ST42Q03         ST42Q04
#> 68038                   (5)                   (5)             (5)
#> 68039 (1) Not useful at all (1) Not useful at all (6) Very Useful
#> 68040                   (3)                   (2)             (3)
#> 68041                   (4) (1) Not useful at all             (5)
#> 68042 (1) Not useful at all                   (4)             (4)
#> 68043                   (2)                   (4)             (3)
#>               ST42Q05
#> 68038             (5)
#> 68039 (6) Very Useful
#> 68040             (4)
#> 68041 (6) Very Useful
#> 68042             (4)
#> 68043             (4)
items29 <- pisaitems[,substr(names(pisaitems), 1,5) == 'ST25Q']
names(items29) <- c("Magazines", "Comic books", "Fiction", 
                   "Non-fiction books", "Newspapers")
l29 <- likert(items29)
summary(l29)
#>                Item      low  neutral     high     mean       sd
#> 1         Magazines 30.21689 21.33091 48.45219 3.254813 1.245086
#> 5        Newspapers 37.29377 15.72688 46.97935 3.140282 1.442299
#> 3           Fiction 41.77380 19.61739 38.60882 2.961111 1.342667
#> 2       Comic books 62.43096 15.78368 21.78536 2.298768 1.292631
#> 4 Non-fiction books 61.42466 19.55493 19.02042 2.322898 1.199176

Created on 2019-11-23 by the reprex package (v0.3.0)

So, in the summary table at the end, in that example, instead of the summary statistics shown, do you want a table for ST24Q01, etc. of the percentages for l29$levels


l29$levels
[1] "Never or almost never" "A few times a year"    "About once a month"    "Several times a month" "Several times a week" 

Again, using pisaitems as a motivating example, are you looking to get summaries by CNT (in this data, Canada, US and Mexico)?

I'm being tedious because as a general rule a precise question opens up better solutions. The problem isn't necessarily looping.

Finally, are you looking for a grand unified table to summarize all your data across all your columns? Or a table for each?

Dear Technocrat,
Thank you so much!
That's a lot easier.

First of all. No, it's 100% not the best way to display the data.
I don't have options here, because I am asked to provide one table for each item (aka one of my cols) displaying the distribution of agreement in the three countries.

Hence, if I can't work out how to loop it, I will need to copy and paste 5 times 79 items individually into a table call. I most well jump out of my office window.

Whether its one extremely long table or separate ones for each column... I have no preference. All I try to avoid is the copy and paste task. I do whatever is easier.
Any suggestions? :slight_smile:

#Packages used

library(likert)
library(tidyverse)
install.packages("xtable")
install.packages("likert")
library(gmodels)
data(pisaitems)

0 Check data

glimpse(pisaitems)
attach(pisaitems)
  1. The principal idea for the body of the loop is below with Case for the first Item (ST24Q01)

ST24Q01 <- CrossTable(CNT, ST24Q01, digits=2, chisq = TRUE)
ST24Q01

because I need it for all items (column ST24Q01:ST42Q05) I try to write a for loop across the columns, excluding the first one (CNT)

First idea was to write a function (NOT WORKING)

fun.prop <- function(pisaitems[,i]) {
  tab[,i] <- round(prop.table(table(CNT,pisaitems[,i]), margin = 1),2 ) %>%
    ftable(table[,i]) 
}


tabs <- apply(pisaitems, fun.prop)

That doesn't work.

So I figured a for loop would be handy and maybe easier, but it didn't work either

for(i in 2:ncol(pisaitems)) {
  tab <- table(pisaitems$CNT, pisaitems[,i])
  prop <- prop.table(tab, margin = 1)
  print(prop)
}

The final product should look like this for all columns (ST24Q01:ST42Q05)


              ST24Q01
CNT             Strongly disagree Disagree Agree Strongly agree
  Canada                     0.26     0.35  0.25           0.14
  Mexico                     0.22     0.37  0.33           0.08
  United States              0.17     0.33  0.34           0.16
1 Like

I'm going to second technocrat's request for a reprex, or at least sample data on a copy/paste friendly format like explained here

Dear andresrcs,
Thank you for the repex help.
I tried to use the data and repel above.
It's not reproducible because I don't know how to create the loop (or another way) that would avoid c&p -ing all vars above (ST24Q01:ST42Q05) individually into a table.
The individual table is rather straight forward table(x,y) is

ST24Q01 <- CrossTable(CNT, ST24Q01, digits=2, chisq = TRUE)
ST24Q01

or

ST24Q01 <- round(prop.table(table(CNT,ST24Q01), margin = 1),2 )

My question is, how can I run this for all items (cols) in pisaitems (see data above)?
My original data frame and the one provided above have 70+ columns and i'd like to avoid copying my code 70+ times. The x remains the same, in the data set above its CNT.

Not sure if that makes it clearer.

Thanks.

Well, I would have preferred a small sample of your data to avoid installing the extra package but it's not a big deal, I think this is what you are trying to do

library(likert)
library(gmodels)
library(tidyverse)

data(pisaitems)
attach(pisaitems)

map(names(pisaitems)[2:4], # Small subset just for exemplification purposes
    ~CrossTable(CNT, eval(as.name(.x)), digits=2, chisq = TRUE))
#> 
#>  
#>    Cell Contents
#> |-------------------------|
#> |                       N |
#> | Chi-square contribution |
#> |           N / Row Total |
#> |           N / Col Total |
#> |         N / Table Total |
#> |-------------------------|
#> 
#>  
#> Total Observations in Table:  65491 
#> 
#>  
#>               | eval(as.name(.x)) 
#>           CNT | Strongly disagree |          Disagree |             Agree |    Strongly agree |         Row Total | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Canada |              5807 |              7938 |              5623 |              3229 |             22597 | 
#>               |             81.84 |              3.80 |            236.60 |            266.34 |                   | 
#>               |              0.26 |              0.35 |              0.25 |              0.14 |              0.35 | 
#>               |              0.39 |              0.34 |              0.28 |              0.46 |                   | 
#>               |              0.09 |              0.12 |              0.09 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Mexico |              8253 |             13872 |             12622 |              2981 |             37728 | 
#>               |             14.86 |              7.82 |            105.10 |            281.82 |                   | 
#>               |              0.22 |              0.37 |              0.33 |              0.08 |              0.58 | 
#>               |              0.55 |              0.59 |              0.63 |              0.42 |                   | 
#>               |              0.13 |              0.21 |              0.19 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> United States |               887 |              1705 |              1755 |               819 |              5166 | 
#>               |             72.33 |             12.11 |             19.94 |            126.22 |                   | 
#>               |              0.17 |              0.33 |              0.34 |              0.16 |              0.08 | 
#>               |              0.06 |              0.07 |              0.09 |              0.12 |                   | 
#>               |              0.01 |              0.03 |              0.03 |              0.01 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>  Column Total |             14947 |             23515 |             20000 |              7029 |             65491 | 
#>               |              0.23 |              0.36 |              0.31 |              0.11 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> 
#>  
#> Statistics for All Table Factors
#> 
#> 
#> Pearson's Chi-squared test 
#> ------------------------------------------------------------
#> Chi^2 =  1228.806     d.f. =  6     p =  2.789342e-262 
#> 
#> 
#>  
#> 
#>  
#>    Cell Contents
#> |-------------------------|
#> |                       N |
#> | Chi-square contribution |
#> |           N / Row Total |
#> |           N / Col Total |
#> |         N / Table Total |
#> |-------------------------|
#> 
#>  
#> Total Observations in Table:  65556 
#> 
#>  
#>               | eval(as.name(.x)) 
#>           CNT | Strongly disagree |          Disagree |             Agree |    Strongly agree |         Row Total | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Canada |              6052 |              7953 |              5568 |              3028 |             22601 | 
#>               |            463.30 |              7.99 |            376.99 |             77.34 |                   | 
#>               |              0.27 |              0.35 |              0.25 |              0.13 |              0.34 | 
#>               |              0.45 |              0.33 |              0.27 |              0.40 |                   | 
#>               |              0.09 |              0.12 |              0.08 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Mexico |              5768 |             13764 |             14280 |              3975 |             37787 | 
#>               |            475.78 |              0.11 |            405.81 |             26.88 |                   | 
#>               |              0.15 |              0.36 |              0.38 |              0.11 |              0.58 | 
#>               |              0.43 |              0.58 |              0.68 |              0.53 |                   | 
#>               |              0.09 |              0.21 |              0.22 |              0.06 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> United States |              1503 |              2094 |              1087 |               484 |              5168 | 
#>               |            195.13 |             25.06 |            192.32 |             19.12 |                   | 
#>               |              0.29 |              0.41 |              0.21 |              0.09 |              0.08 | 
#>               |              0.11 |              0.09 |              0.05 |              0.06 |                   | 
#>               |              0.02 |              0.03 |              0.02 |              0.01 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>  Column Total |             13323 |             23811 |             20935 |              7487 |             65556 | 
#>               |              0.20 |              0.36 |              0.32 |              0.11 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> 
#>  
#> Statistics for All Table Factors
#> 
#> 
#> Pearson's Chi-squared test 
#> ------------------------------------------------------------
#> Chi^2 =  2265.813     d.f. =  6     p =  0 
#> 
#> 
#>  
#> 
#>  
#>    Cell Contents
#> |-------------------------|
#> |                       N |
#> | Chi-square contribution |
#> |           N / Row Total |
#> |           N / Col Total |
#> |         N / Table Total |
#> |-------------------------|
#> 
#>  
#> Total Observations in Table:  65414 
#> 
#>  
#>               | eval(as.name(.x)) 
#>           CNT | Strongly disagree |          Disagree |             Agree |    Strongly agree |         Row Total | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Canada |              5697 |              7154 |              7558 |              2172 |             22581 | 
#>               |            168.32 |             28.41 |             39.01 |              8.20 |                   | 
#>               |              0.25 |              0.32 |              0.33 |              0.10 |              0.35 | 
#>               |              0.41 |              0.32 |              0.32 |              0.37 |                   | 
#>               |              0.09 |              0.11 |              0.12 |              0.03 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Mexico |              6949 |             13106 |             14276 |              3345 |             37676 | 
#>               |            139.52 |             12.17 |             38.95 |              1.16 |                   | 
#>               |              0.18 |              0.35 |              0.38 |              0.09 |              0.58 | 
#>               |              0.50 |              0.59 |              0.61 |              0.57 |                   | 
#>               |              0.11 |              0.20 |              0.22 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> United States |              1254 |              1812 |              1691 |               400 |              5157 | 
#>               |             22.83 |              2.97 |             14.44 |              9.47 |                   | 
#>               |              0.24 |              0.35 |              0.33 |              0.08 |              0.08 | 
#>               |              0.09 |              0.08 |              0.07 |              0.07 |                   | 
#>               |              0.02 |              0.03 |              0.03 |              0.01 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>  Column Total |             13900 |             22072 |             23525 |              5917 |             65414 | 
#>               |              0.21 |              0.34 |              0.36 |              0.09 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> 
#>  
#> Statistics for All Table Factors
#> 
#> 
#> Pearson's Chi-squared test 
#> ------------------------------------------------------------
#> Chi^2 =  485.4731     d.f. =  6     p =  1.131549e-101 
#> 
#> 
#> 
#> [[1]]
#> [[1]]$t
#>                y
#> x               Strongly disagree Disagree Agree Strongly agree
#>   Canada                     5807     7938  5623           3229
#>   Mexico                     8253    13872 12622           2981
#>   United States               887     1705  1755            819
#> 
#> [[1]]$prop.row
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.25698102 0.35128557 0.24883834     0.14289507
#>   Mexico               0.21875000 0.36768448 0.33455259     0.07901293
#>   United States        0.17169957 0.33004259 0.33972125     0.15853659
#> 
#> [[1]]$prop.col
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.38850605 0.33757176 0.28115000     0.45938256
#>   Mexico               0.55215093 0.58992133 0.63110000     0.42410016
#>   United States        0.05934301 0.07250691 0.08775000     0.11651729
#> 
#> [[1]]$prop.tbl
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.08866867 0.12120749 0.08585913     0.04930448
#>   Mexico               0.12601732 0.21181536 0.19272877     0.04551770
#>   United States        0.01354385 0.02603411 0.02679758     0.01250554
#> 
#> [[1]]$chisq
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  t
#> X-squared = 1228.8, df = 6, p-value < 2.2e-16
#> 
#> 
#> 
#> [[2]]
#> [[2]]$t
#>                y
#> x               Strongly disagree Disagree Agree Strongly agree
#>   Canada                     6052     7953  5568           3028
#>   Mexico                     5768    13764 14280           3975
#>   United States              1503     2094  1087            484
#> 
#> [[2]]$prop.row
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.26777576 0.35188708 0.24636078     0.13397637
#>   Mexico               0.15264509 0.36425226 0.37790775     0.10519491
#>   United States        0.29082817 0.40518576 0.21033282     0.09365325
#> 
#> [[2]]$prop.col
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.45425205 0.33400529 0.26596609     0.40443435
#>   Mexico               0.43293553 0.57805216 0.68211130     0.53092026
#>   United States        0.11281243 0.08794255 0.05192262     0.06464539
#> 
#> [[2]]$prop.tbl
#>                y
#> x               Strongly disagree    Disagree       Agree Strongly agree
#>   Canada              0.092318018 0.121316127 0.084935017    0.046189517
#>   Mexico              0.087985844 0.209957899 0.217829032    0.060635182
#>   United States       0.022926963 0.031942156 0.016581244    0.007383001
#> 
#> [[2]]$chisq
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  t
#> X-squared = 2265.8, df = 6, p-value < 2.2e-16
#> 
#> 
#> 
#> [[3]]
#> [[3]]$t
#>                y
#> x               Strongly disagree Disagree Agree Strongly agree
#>   Canada                     5697     7154  7558           2172
#>   Mexico                     6949    13106 14276           3345
#>   United States              1254     1812  1691            400
#> 
#> [[3]]$prop.row
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.25229175 0.31681502 0.33470617     0.09618706
#>   Mexico               0.18444102 0.34786071 0.37891496     0.08878331
#>   United States        0.24316463 0.35136707 0.32790382     0.07756448
#> 
#> [[3]]$prop.col
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.40985612 0.32412106 0.32127524     0.36707791
#>   Mexico               0.49992806 0.59378398 0.60684378     0.56532026
#>   United States        0.09021583 0.08209496 0.07188098     0.06760183
#> 
#> [[3]]$prop.tbl
#>                y
#> x               Strongly disagree    Disagree       Agree Strongly agree
#>   Canada              0.087091448 0.109364968 0.115541016    0.033203901
#>   Mexico              0.106231082 0.200354664 0.218240744    0.051135842
#>   United States       0.019170208 0.027700492 0.025850735    0.006114899
#> 
#> [[3]]$chisq
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  t
#> X-squared = 485.47, df = 6, p-value < 2.2e-16

Great! The ST24Q01 table at the end shows exactly the target form for each of the columns. So, let's take it in two parts:

  1. Write a function to do it once.
  2. Find a function to repeat at often as required
suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(likert))
suppressPackageStartupMessages(library(purrr))

data(pisaitems)

options(digits = 1)

make_p_tab <- function(x) {
  col_df <- pisaitems %>% select(CNT, x) %>% filter(!is.na(x)) %>%
  table() %>% prop.table(.,1)
}

# Using all columns would make the reprex too long
# to_do <- colnames(pisaitems)[2:ncol(pisaitems)]
# We'll just use the first 10 after CNT

to_do <- colnames(pisaitems)[2:11]
map(to_do, make_p_tab)
#> [[1]]
#>                ST24Q01
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.26     0.35  0.25           0.14
#>   Mexico                     0.22     0.37  0.33           0.08
#>   United States              0.17     0.33  0.34           0.16
#> 
#> [[2]]
#>                ST24Q02
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.27     0.35  0.25           0.13
#>   Mexico                     0.15     0.36  0.38           0.11
#>   United States              0.29     0.41  0.21           0.09
#> 
#> [[3]]
#>                ST24Q03
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.25     0.32  0.33           0.10
#>   Mexico                     0.18     0.35  0.38           0.09
#>   United States              0.24     0.35  0.33           0.08
#> 
#> [[4]]
#>                ST24Q04
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.31     0.40  0.20           0.09
#>   Mexico                     0.21     0.40  0.31           0.08
#>   United States              0.25     0.44  0.23           0.08
#> 
#> [[5]]
#>                ST24Q05
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.23     0.27  0.38           0.12
#>   Mexico                     0.15     0.27  0.43           0.14
#>   United States              0.29     0.33  0.31           0.07
#> 
#> [[6]]
#>                ST24Q06
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.40     0.36  0.14           0.10
#>   Mexico                     0.45     0.44  0.09           0.03
#>   United States              0.33     0.41  0.16           0.10
#> 
#> [[7]]
#>                ST24Q07
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.21     0.27  0.35           0.17
#>   Mexico                     0.16     0.38  0.38           0.08
#>   United States              0.19     0.28  0.37           0.17
#> 
#> [[8]]
#>                ST24Q08
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                      0.2      0.4   0.3            0.1
#>   Mexico                      0.1      0.3   0.4            0.2
#>   United States               0.2      0.4   0.3            0.1
#> 
#> [[9]]
#>                ST24Q09
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                     0.38     0.38  0.14           0.10
#>   Mexico                     0.30     0.47  0.18           0.05
#>   United States              0.31     0.41  0.18           0.11
#> 
#> [[10]]
#>                ST24Q10
#> CNT             Strongly disagree Disagree Agree Strongly agree
#>   Canada                      0.2      0.3   0.4            0.1
#>   Mexico                      0.1      0.3   0.5            0.2
#>   United States               0.2      0.3   0.4            0.1

Created on 2019-11-23 by the reprex package (v0.3.0)

In practice, you'd generalize the function to take additional arguments, rather than hardwiring pisaitems and CNT.

Thank you, thank you thank you!

Thats what I am looking for :slight_smile:

One last question: how does eval(as.name(.x)) print the variable name?
Currently, I can't see in your code which variable is displayed.

I apologize for the terrible code snipped and not subsetting it.

Thanks to both of you saving my Sunday from long and tedious c&p work!

1 Like

@ Technocrat: Thanks! So beautiful <3

I'll let @andresrcs answer the question about eval

One of the wonderful things about R is that it's really just like school algebra f(x) = y, and the focus is on results, meaning that there's usually more than one way to do things. That's why I was being so didactic about the question being more important than the how of going about answering it.

People like me who come to R from a programming background in languages like the C family or Python/Ruby, tend to have a hard time grasping the functional character of what we do here. While base R does have for loops and other procedural/imperative tools, it's not where most of us want to spend our time.

We want to say take this object and give me that object if I tell you these additional things (perhaps). Some of how an R package may accomplish that is buried deep under the hood in a tried and true FORTRAN program. You and I shouldn't have to care!

One thing I could have mentioned is that you can save the result

combined <- map(to_do, make_p_tab)

which will give you a list of tables to subset.

Yeah, I guess so. It's not very intuitive for me and I struggle with all the different functions and packages.
When it works, it's brilliant.
Have a good evening and thanks again.

1 Like

I used to complain that help() needed its own help.

I was kind of abashed when I tried help(help).

But the function paradigm really helped me get over it: there are arguments and results. Some arguments are required, some are optional, some have defaults. Working the examples also helps, especially if you apply the structure function str to see the internals.

Dear @andresrcs,

I am really wondering how the column name would appear in the output. Since CrossTable is more versatile, easier to read in RMarkdown and I never know what I need next this would be my last step to empowerment with tabs.

Thank you and happy Sunday!

Dear technocrat,
Yes, it does get easier once the head is wrapped around the structure. However, the leap from understanding the help to being creative yourself is rather daunting.
Thanks for the encouragement.

In case I want to modify your code

make_x_tab <- function(x) { 
  col_df <- pisaitems  %>% select(CNT, x) %>% filter(!is.na(x)) %>%
    CrossTable(CNT,., digits=2, chisq = TRUE, prop.chisq = FALSE, format= "SPSS")
}

to_do <- colnames(pisaitems)[2:11]
combined <- map(to_do, make_x_tab)

I receive an error message

 Error in CrossTable(CNT, ., digits = 2, chisq = TRUE, prop.chisq = FALSE,  : 
  x and y must have the same length 

Why does it work in your case to replace the data with . and not in mine?

Best,
M.

I didn't notice that unwanted behavior, it is a little counterintuitive for me so I wasn't expecting it. I have found this walk-around solution but very likely there is a more elegant one.

library(likert)
library(gmodels)
library(tidyverse)
library(rlang)

data(pisaitems)
attach(pisaitems)

map(names(pisaitems)[2:4],
    ~CrossTable(CNT, eval_bare(sym(.x)),
                digits=2,
                chisq = TRUE,
                dnn = c("CNT", as_string(.x)))
    )
#> 
#>  
#>    Cell Contents
#> |-------------------------|
#> |                       N |
#> | Chi-square contribution |
#> |           N / Row Total |
#> |           N / Col Total |
#> |         N / Table Total |
#> |-------------------------|
#> 
#>  
#> Total Observations in Table:  65491 
#> 
#>  
#>               | ST24Q01 
#>           CNT | Strongly disagree |          Disagree |             Agree |    Strongly agree |         Row Total | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Canada |              5807 |              7938 |              5623 |              3229 |             22597 | 
#>               |             81.84 |              3.80 |            236.60 |            266.34 |                   | 
#>               |              0.26 |              0.35 |              0.25 |              0.14 |              0.35 | 
#>               |              0.39 |              0.34 |              0.28 |              0.46 |                   | 
#>               |              0.09 |              0.12 |              0.09 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Mexico |              8253 |             13872 |             12622 |              2981 |             37728 | 
#>               |             14.86 |              7.82 |            105.10 |            281.82 |                   | 
#>               |              0.22 |              0.37 |              0.33 |              0.08 |              0.58 | 
#>               |              0.55 |              0.59 |              0.63 |              0.42 |                   | 
#>               |              0.13 |              0.21 |              0.19 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> United States |               887 |              1705 |              1755 |               819 |              5166 | 
#>               |             72.33 |             12.11 |             19.94 |            126.22 |                   | 
#>               |              0.17 |              0.33 |              0.34 |              0.16 |              0.08 | 
#>               |              0.06 |              0.07 |              0.09 |              0.12 |                   | 
#>               |              0.01 |              0.03 |              0.03 |              0.01 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>  Column Total |             14947 |             23515 |             20000 |              7029 |             65491 | 
#>               |              0.23 |              0.36 |              0.31 |              0.11 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> 
#>  
#> Statistics for All Table Factors
#> 
#> 
#> Pearson's Chi-squared test 
#> ------------------------------------------------------------
#> Chi^2 =  1228.806     d.f. =  6     p =  2.789342e-262 
#> 
#> 
#>  
#> 
#>  
#>    Cell Contents
#> |-------------------------|
#> |                       N |
#> | Chi-square contribution |
#> |           N / Row Total |
#> |           N / Col Total |
#> |         N / Table Total |
#> |-------------------------|
#> 
#>  
#> Total Observations in Table:  65556 
#> 
#>  
#>               | ST24Q02 
#>           CNT | Strongly disagree |          Disagree |             Agree |    Strongly agree |         Row Total | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Canada |              6052 |              7953 |              5568 |              3028 |             22601 | 
#>               |            463.30 |              7.99 |            376.99 |             77.34 |                   | 
#>               |              0.27 |              0.35 |              0.25 |              0.13 |              0.34 | 
#>               |              0.45 |              0.33 |              0.27 |              0.40 |                   | 
#>               |              0.09 |              0.12 |              0.08 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Mexico |              5768 |             13764 |             14280 |              3975 |             37787 | 
#>               |            475.78 |              0.11 |            405.81 |             26.88 |                   | 
#>               |              0.15 |              0.36 |              0.38 |              0.11 |              0.58 | 
#>               |              0.43 |              0.58 |              0.68 |              0.53 |                   | 
#>               |              0.09 |              0.21 |              0.22 |              0.06 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> United States |              1503 |              2094 |              1087 |               484 |              5168 | 
#>               |            195.13 |             25.06 |            192.32 |             19.12 |                   | 
#>               |              0.29 |              0.41 |              0.21 |              0.09 |              0.08 | 
#>               |              0.11 |              0.09 |              0.05 |              0.06 |                   | 
#>               |              0.02 |              0.03 |              0.02 |              0.01 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>  Column Total |             13323 |             23811 |             20935 |              7487 |             65556 | 
#>               |              0.20 |              0.36 |              0.32 |              0.11 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> 
#>  
#> Statistics for All Table Factors
#> 
#> 
#> Pearson's Chi-squared test 
#> ------------------------------------------------------------
#> Chi^2 =  2265.813     d.f. =  6     p =  0 
#> 
#> 
#>  
#> 
#>  
#>    Cell Contents
#> |-------------------------|
#> |                       N |
#> | Chi-square contribution |
#> |           N / Row Total |
#> |           N / Col Total |
#> |         N / Table Total |
#> |-------------------------|
#> 
#>  
#> Total Observations in Table:  65414 
#> 
#>  
#>               | ST24Q03 
#>           CNT | Strongly disagree |          Disagree |             Agree |    Strongly agree |         Row Total | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Canada |              5697 |              7154 |              7558 |              2172 |             22581 | 
#>               |            168.32 |             28.41 |             39.01 |              8.20 |                   | 
#>               |              0.25 |              0.32 |              0.33 |              0.10 |              0.35 | 
#>               |              0.41 |              0.32 |              0.32 |              0.37 |                   | 
#>               |              0.09 |              0.11 |              0.12 |              0.03 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>        Mexico |              6949 |             13106 |             14276 |              3345 |             37676 | 
#>               |            139.52 |             12.17 |             38.95 |              1.16 |                   | 
#>               |              0.18 |              0.35 |              0.38 |              0.09 |              0.58 | 
#>               |              0.50 |              0.59 |              0.61 |              0.57 |                   | 
#>               |              0.11 |              0.20 |              0.22 |              0.05 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> United States |              1254 |              1812 |              1691 |               400 |              5157 | 
#>               |             22.83 |              2.97 |             14.44 |              9.47 |                   | 
#>               |              0.24 |              0.35 |              0.33 |              0.08 |              0.08 | 
#>               |              0.09 |              0.08 |              0.07 |              0.07 |                   | 
#>               |              0.02 |              0.03 |              0.03 |              0.01 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#>  Column Total |             13900 |             22072 |             23525 |              5917 |             65414 | 
#>               |              0.21 |              0.34 |              0.36 |              0.09 |                   | 
#> --------------|-------------------|-------------------|-------------------|-------------------|-------------------|
#> 
#>  
#> Statistics for All Table Factors
#> 
#> 
#> Pearson's Chi-squared test 
#> ------------------------------------------------------------
#> Chi^2 =  485.4731     d.f. =  6     p =  1.131549e-101 
#> 
#> 
#> 
#> [[1]]
#> [[1]]$t
#>                y
#> x               Strongly disagree Disagree Agree Strongly agree
#>   Canada                     5807     7938  5623           3229
#>   Mexico                     8253    13872 12622           2981
#>   United States               887     1705  1755            819
#> 
#> [[1]]$prop.row
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.25698102 0.35128557 0.24883834     0.14289507
#>   Mexico               0.21875000 0.36768448 0.33455259     0.07901293
#>   United States        0.17169957 0.33004259 0.33972125     0.15853659
#> 
#> [[1]]$prop.col
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.38850605 0.33757176 0.28115000     0.45938256
#>   Mexico               0.55215093 0.58992133 0.63110000     0.42410016
#>   United States        0.05934301 0.07250691 0.08775000     0.11651729
#> 
#> [[1]]$prop.tbl
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.08866867 0.12120749 0.08585913     0.04930448
#>   Mexico               0.12601732 0.21181536 0.19272877     0.04551770
#>   United States        0.01354385 0.02603411 0.02679758     0.01250554
#> 
#> [[1]]$chisq
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  t
#> X-squared = 1228.8, df = 6, p-value < 2.2e-16
#> 
#> 
#> 
#> [[2]]
#> [[2]]$t
#>                y
#> x               Strongly disagree Disagree Agree Strongly agree
#>   Canada                     6052     7953  5568           3028
#>   Mexico                     5768    13764 14280           3975
#>   United States              1503     2094  1087            484
#> 
#> [[2]]$prop.row
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.26777576 0.35188708 0.24636078     0.13397637
#>   Mexico               0.15264509 0.36425226 0.37790775     0.10519491
#>   United States        0.29082817 0.40518576 0.21033282     0.09365325
#> 
#> [[2]]$prop.col
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.45425205 0.33400529 0.26596609     0.40443435
#>   Mexico               0.43293553 0.57805216 0.68211130     0.53092026
#>   United States        0.11281243 0.08794255 0.05192262     0.06464539
#> 
#> [[2]]$prop.tbl
#>                y
#> x               Strongly disagree    Disagree       Agree Strongly agree
#>   Canada              0.092318018 0.121316127 0.084935017    0.046189517
#>   Mexico              0.087985844 0.209957899 0.217829032    0.060635182
#>   United States       0.022926963 0.031942156 0.016581244    0.007383001
#> 
#> [[2]]$chisq
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  t
#> X-squared = 2265.8, df = 6, p-value < 2.2e-16
#> 
#> 
#> 
#> [[3]]
#> [[3]]$t
#>                y
#> x               Strongly disagree Disagree Agree Strongly agree
#>   Canada                     5697     7154  7558           2172
#>   Mexico                     6949    13106 14276           3345
#>   United States              1254     1812  1691            400
#> 
#> [[3]]$prop.row
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.25229175 0.31681502 0.33470617     0.09618706
#>   Mexico               0.18444102 0.34786071 0.37891496     0.08878331
#>   United States        0.24316463 0.35136707 0.32790382     0.07756448
#> 
#> [[3]]$prop.col
#>                y
#> x               Strongly disagree   Disagree      Agree Strongly agree
#>   Canada               0.40985612 0.32412106 0.32127524     0.36707791
#>   Mexico               0.49992806 0.59378398 0.60684378     0.56532026
#>   United States        0.09021583 0.08209496 0.07188098     0.06760183
#> 
#> [[3]]$prop.tbl
#>                y
#> x               Strongly disagree    Disagree       Agree Strongly agree
#>   Canada              0.087091448 0.109364968 0.115541016    0.033203901
#>   Mexico              0.106231082 0.200354664 0.218240744    0.051135842
#>   United States       0.019170208 0.027700492 0.025850735    0.006114899
#> 
#> [[3]]$chisq
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  t
#> X-squared = 485.47, df = 6, p-value < 2.2e-16

Dear @andresrcs,

Thank you very much. I feel well equipped for any future tabulation task in my life.

I appreciate you support a lot and apologize again for the terrible description and code snippets.

Enjoy your weekend.

Best,
M

I'm glad to be of service.

If your question's been answered (even by you!), would you mind choosing a solution? It helps other people see which questions still need help, or find solutions if they have similar problems. Here’s how to do it:

1 Like

Done. Thanks. All the little things to learn in a forum.