Reputation: 55
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
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
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
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