Arie
Arie

Reputation: 55

How do I get a table as output instead of a list when using the table-function and one of my factors is missing a level?

I am processing the results of a questionnaire and want to present the responses on several related Yes/No questions in one single table. On one of these questions all respondents answered "No". It appears that as a result of missing one response level in this question, the table-function in R returns a list instead of a table.

Adding factor level "Yes" to the question with zero "Yes" responses, does not solve the problem. The code I present below, by the way, works fine for questions where respondents answered either "Yes" or "No".

This code relates to three questions answered by five respondents and illustrates my questionnaire.

q1 <- c("Yes", "Yes", "Yes", "Yes", "No")
q2 <- c("No", "No", "No", "No", "No") # our culprit
q3 <- c("Yes", "Yes", "No", "No", "No")

From this data I wish to create the following table:

     q1  q2  q3
Yes   4   0   2
No    1   5   3

Realizing that factor q2 has only one level I wrote:

q2 <- factor(q2, levels = c("Yes", "No"))

I combine the question vectors in a dataframe and apply the table-function to its columns:

df <- data.frame(q1, q2, q3)
apply(df, 2, table)

The actual output of the table-function is not the table above but the list below:

$q1

 No Yes 
  1   4 

$q2

No 
 5 

$q3

 No Yes 
  3   2

Upvotes: 1

Views: 600

Answers (3)

Onyambu
Onyambu

Reputation: 79198

table(stack(list(q1=q1,q2=q2,q3=q3)))

      ind
values q1 q2 q3
   No   1  5  3
   Yes  4  0  2

Upvotes: 1

MrFlick
MrFlick

Reputation: 206177

I think it's better to explicitly list the labels across all the values you want to measure. Then you can convert to factor and do the sum

vals <- c("Yes", "No")
df <- data.frame(q1, q2, q3)
sapply(lapply(df, factor, levels=vals), table)

Here the inner lapply creates the factors with the proper levels for all lists, and the sapply runs the table()

Upvotes: 0

kstew
kstew

Reputation: 1114

Using dplyr, you can count each grouping then use fill=0 when spreading to get the desired table.

df %>% gather(k,v) %>% 
  count(k,v) %>% spread(k,n,fill=0)

# A tibble: 2 x 4
  v        q1    q2    q3
  <chr> <dbl> <dbl> <dbl>
1 No        1     5     3
2 Yes       4     0     2

Upvotes: 1

Related Questions