开发者

Crosstab with multiple items

In SPSS, it is (r开发者_开发知识库elatively) easy to create a cross tab with multiple variables using the factors (or values) as the table heading. So, something like the following (made up data, etc.). Q1, Q2, and Q3 each have either a 1, a 2, or a 3 for each person. I just left these as numbers, but they could be factors, neither seemed to help solve the problem.

                        1 (very Often)   2 (Rarely)   3 (Never)
   Q1. Likes it           12              15             13
   Q2. Recommends it      22              11             10
   Q3. Used it            22              12             9

In SPSS, one can even request row, column, or total percentages.

I've tried table(), ftable(), xtab(), CrossTable() from gmodels, and CrossTable() from descr, and none of these can handle (afaik) multiple variables; they mostly seem to handle 1 variable crossed with another variable, and the 3rd creates layers.

Is there a package with some good cross tabbing/table examples that I could use to figure this out? I'm sure I'm missing something simple, so I appreciate you pointing out what I missed. Perhaps I have to generate each row as a separate list and then make a dataframe and print the dataframe?

UPDATE: I've now discovered ctab() in package catspec, which is also on the right track. It's interesting that R has no consistent equivalent to Ctables in SPSS, which is basically a "tabbing" tool ala the old tabulate tools used for survey research. ctab() is trying, and is an admirable 1st step... but you still can't make this table (above) with it.


The Hmisc package has the summary.formula function that can do something along the lines you want. It is very flexible, so look at the help page for examples, but here is an application to your problem:

library(Hmisc)
dd <- data.frame(Q1=sample(1:3, 20, replace=T), Q2=sample(1:3, 20, replace=T), 
                 Q3=sample(1:3, 20, replace=T))  #fake data
summary(~Q1+Q2+Q3, data=dd, fun=table)

This gives the following result:

 Descriptive Statistics  (N=20)

 +------+-------+
 |      |       |
 +------+-------+
 |Q1 : 1|25% (5)|
 +------+-------+
 |    2 |45% (9)|
 +------+-------+
 |    3 |30% (6)|
 +------+-------+
 |Q2 : 1|30% (6)|
 +------+-------+
 |    2 |35% (7)|
 +------+-------+
 |    3 |35% (7)|
 +------+-------+
 |Q3 : 1|35% (7)|
 +------+-------+
 |    2 |30% (6)|
 +------+-------+
 |    3 |35% (7)|
 +------+-------+

The possible values are given in rows, because it has the flexibility of different sets of values for different variables. You might be able to play with the function parameters (like method and fun) to get the other direction.


Modifying a previous example

library(Hmisc)
library(plyr)
dd <- data.frame(q1=sample(1:3, 20, replace=T),
 q2=sample(1:3, 20, replace=T), 
 q3=sample(1:3, 20, replace=T))  #fake data

cross <- ldply(describe(dd), function(x) x$values[1,])[-1]

rownames(cross) <- c("Q1. Likes it","Q2. Recommends it","Q3. Used it")
names(cross) <- c("1 (very Often)","2 (Rarely)","3 (Never)")

Now cross looks like this

> cross
                  1 (very Often) 2 (Rarely) 3 (Never)
Q1. Likes it                   4         10         6
Q2. Recommends it              7          9         4
Q3. Used it                    6          4        10


The underlying issue is that this data is not in tidy format. Crosstabbing multiple variables will be easier when the data is reshaped into "long" form. We can do that with gather from the tidyr package.

After reshaping, many crosstab functions will work; I'll use tabyl from the janitor package (since - full disclosure - I maintain that package and built the function for this purpose).

# Create reproducible sample data
set.seed(1)
possible_values <- c("1 (Very Often)", "2 (Rarely)", "3 (Never)")
some_values <- sample(possible_values, 100, replace = TRUE)
dat <- data.frame(Q1 = some_values[1:25], Q2 = some_values[26:50], 
                 Q3 = some_values[51:75], Q4 = some_values[76:100])

library(tidyr)
library(janitor)

dat %>%
  gather(question, response) %>% 
  tabyl(question, response)
#>   question 1 (Very Often) 2 (Rarely) 3 (Never)
#> 1       Q1              8          8         9
#> 2       Q2              4         11        10
#> 3       Q3              8         12         5
#> 4       Q4              7          7        11

From there, you can format with functions like janitor::adorn_percentages().


just check Hadley Wickham's reshape package. AFAIS, you need cast function from the package.


xtabs has a formula interface that can take some practice to get used to, but this can be done. If you have the data in a dataframe df and your variables are called ques and resp, you can use:

xtabs(~ques+resp,data=df)

For example:

> t1 <- rep(c("A","B","C"),5)
> t2 <- rpois(15,4)
> df <- data.frame(ques=t1,resp=t2)
> xtabs(~ques+resp,data=df)
     resp
names 2 3 4 5 6 7 9
    A 1 0 2 1 0 0 1
    B 1 0 0 2 1 1 0
    C 1 2 0 1 0 1 0


Check out tableStack() from the epiDisplay package. I think it might be what you're looking for.


You could use a custom function to use rbind() on several tables, something like this:

multitab <- function(...){
   tabs<-list(...)
   tablist<-lapply(tabs,table)
   bigtab<-t(sapply(tablist,rbind))
   bigtab } 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜