Max
Max

Reputation: 121

Count Response Choices per Participant, include response choices with 0 responses

I have a dataset which contains the responses of multiple participants to emotional faces. The participants responded with which emotion they think they saw. There were multiple trials per participant. Imagine, there were 4 answer possibilities: Disgust, Sadness, Anger, and Neutral. I want to calculate the proportion each participant selected each answer possibility. When I recently asked a similar question, I got provided with a solution, which later turned out to be incomplete for my needs. Therefore, I opened this new question.

Here is some example data:

Response <- c("Disgust", "Sadness", "Disgust", "Anger", "Anger", "Neutral", "Anger", "Disgust", "Happiness") #create example data
ResponseNum <- c(1,2,1,3,3,4,3,1,5) #Response, but expressed in Numbers
ppnum <- c(1,1,1,2,2,2,3,3,3)
df2a_anger <- as.data.frame(cbind(Response, ResponseNum, ppnum)) #create dataframe
df2a_anger$ResponseNum <- as.numeric(as.character(df2a_anger$ResponseNum)) # make numeric

Here is some example code:

library(dplyr)

df2a_anger %>%
    count(ppnum, ResponseNum) %>%
    group_by(ppnum) %>%
    mutate(n = n/sum(n))

An alternative I found myself trying to solve my problem involves the aggregate function, however both suffer the same problem: They do not count when an response option has not been chosen: For example, the code outputs that participant 1 chose Disgust 66% and Sadness 33%. I also want it to output that participant 1 chose neutral and angry for 0%. Does anyone have any idea how to get R to do that?

Upvotes: 0

Views: 317

Answers (3)

Matt
Matt

Reputation: 7405

You could use janitor:

library(janitor)
library(dplyr)

df2a_anger %>% 
  tabyl(Response, ppnum) %>% 
  adorn_percentages(denominator = 'col') %>% 
  adorn_pct_formatting()

Which gives you:

Response     1     2     3
     Anger  0.0% 66.7% 33.3%
   Disgust 66.7%  0.0% 33.3%
 Happiness  0.0%  0.0% 33.3%
   Neutral  0.0% 33.3%  0.0%
   Sadness 33.3%  0.0%  0.0%

Or, if you want the response options as column headers:

df2a_anger %>% 
  tabyl(ppnum, Response) %>% 
  adorn_percentages(denominator = 'row') %>% 
  adorn_pct_formatting()

Which gives you:

 ppnum Anger Disgust Happiness Neutral Sadness
     1  0.0%   66.7%      0.0%    0.0%   33.3%
     2 66.7%    0.0%      0.0%   33.3%    0.0%
     3 33.3%   33.3%     33.3%    0.0%    0.0%

Upvotes: 1

Martin Wettstein
Martin Wettstein

Reputation: 2894

The basic table() function should suffice in this case.

Tip: If you combine character vectors and numeric vectors to a data.frame, don't use cbind(), as this forces all columns to the same atomic object class. Use the data.frame() function to combine them piecewise.

Response <- c("Disgust", "Sadness", "Disgust", "Anger", "Anger", "Neutral", "Anger", "Disgust", "Happiness") #create example data
ResponseNum <- c(1,2,1,3,3,4,3,1,5) #Response, but expressed in Numbers
ppnum <- c(1,1,1,2,2,2,3,3,3)
df2a_anger <- data.frame("Response" = Response,
                         "ResponseNum" = ResponseNum,
                         "Pnum" = ppnum) #create dataframe

table(df2a_anger$Pnum,df2a_anger$Response)
table(df2a_anger$Pnum,df2a_anger$ResponseNum)

absolutes = as.matrix(table(df2a_anger$Pnum,df2a_anger$Response))
proportions = absolutes/rowSums(absolutes)
barplot(t(proportions),legend.text = colnames(proportions),beside=T,ylim=c(0,1),xlab="Respondent")

This code will give you two tables, one with the absolute counts per respondent and the other with proportions.

And, as a bonus, it gives you this plot: barplot

Upvotes: 0

lroha
lroha

Reputation: 34601

One way is to use forcats::fct_count():

library(dplyr)
library(forcats)

df2a_anger %>%
  mutate(Response = factor(Response)) %>%
  group_by(ppnum) %>%
  summarise(res = fct_count(Response, prop = TRUE))

`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 15 x 4
   ppnum f             n     p
   <chr> <fct>     <int> <dbl>
 1 1     Anger         0 0    
 2 1     Disgust       2 0.667
 3 1     Happiness     0 0    
 4 1     Neutral       0 0    
 5 1     Sadness       1 0.333
 6 2     Anger         2 0.667
 7 2     Disgust       0 0    
 8 2     Happiness     0 0    
 9 2     Neutral       1 0.333
10 2     Sadness       0 0    
11 3     Anger         1 0.333
12 3     Disgust       1 0.333
13 3     Happiness     1 0.333
14 3     Neutral       0 0    
15 3     Sadness       0 0    

Upvotes: 1

Related Questions