Reputation: 31
I have aggregate summary results (N, mean, sd) for survey-questions for different subgroups (e.g. by course, age-group, gender). I would like to identify those subgroups where statistically significant entries exist to be then able to probe the results further. Ideally this should all work within the process of prepping the data for a report in R Markdown using tidyverse / dplyr.
My data look like this:
> head(demo, 11)
# A tibble: 11 x 7
# Groups: qid, subgroup [3]
qid question subgroup name N mean sd
<int> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 1 noise NA total 214 3.65 1.03
2 1 noise course A 11 4 0.77
3 1 noise course B 47 3.55 1.16
4 1 noise course C 31 3.29 1.24
5 1 noise course D 40 3.8 0.85
6 1 noise course E 16 3.38 1.09
7 1 noise course F 11 3.55 1.13
8 1 noise course G 25 4.12 0.73
9 1 noise course H 25 3.68 0.85
10 1 noise gender f 120 3.65 1.07
11 1 noise gender m 93 3.67 0.98
What I want, is a new column, indicating TRUE if there is a statistically significant difference within an subgroup for a given question, FALSE if otherwise. Like sigdiff below:
qid question subgroup name N mean sd sigdiff
<int> <chr> <chr> <chr> <dbl> <dbl> <dbl> <lgl>
2 1 noise course A 11 4 0.77 FALSE
3 1 noise course B 47 3.55 1.16 FALSE
4 1 noise course C 31 3.29 1.24 FALSE
5 1 noise course D 40 3.8 0.85 FALSE
6 1 noise course E 16 3.38 1.09 FALSE
7 1 noise course F 11 3.55 1.13 FALSE
8 1 noise course G 25 4.12 0.73 FALSE
9 1 noise course H 25 3.68 0.85 FALSE
Now, a very neat way to approach this seemed to be to determine if there's a significant difference beetween any groups by adapting this approach based on the rpsychi package.
I failed, however to adapt this to apply to my grouped tibble. My (failing) approach was to try to simply call a function doing the ANOVA by dplyr's newish group_map:
if(!require(rpsychi)){install.packages("rpsychi")}
library(rpsychi)
if(!require(tidyverse)){install.packages("tidyverse")}
library(tidyverse)
#' function establishing significant difference
#' between survey answers within subgroups
anovagrptest <- function(grpsum){
anovaresult <- ind.oneway.second(grpsum$mean, grpsum$sd, grpsum$N, sig.level = 0.05)
# compare critical F Value
fcrit <- qf(.95, anovaresult$anova.table$df[1], anovaresult$anova.table$df[2])
if(anovaresult$anova.table$F[1] > fcrit){return(TRUE)
}else{return(FALSE)}
}
#' pass the subset of the data for the group to the function which
#' "returns a list of results from calling .f on each group"
relquestions <- demo %>%
group_by(qid, subgroup) %>%
group_map(~ anovagrptest(.x))
The code aborts due to "error in delta.upper + dfb : non-numeric argument for binary operator". Ideas much appreciated.
Upvotes: 3
Views: 1149
Reputation: 16978
I think your row with NA
causes your problem. First of all: I don't think you need that mapping function (but to be honest I'm not 100 % sure).
demo %>%
select(-id) %>%
group_by(qid, subgroup) %>%
mutate(new_column = ind.oneway.second(mean, sd, N, sig.level = 0.05) %>%
{qf(.95, .[["anova.table"]][["df"]][1], .[["anova.table"]][["df"]][2]) < .[["anova.table"]][["F"]][1]})
causes
Error: Problem with `mutate()` input `new_column`.
x non-numeric argument for binary operator
i Input `new_column` is ``%>%`(...)`.
i The error occured in group 3: qid = 1, subgroup = NA.
Run `rlang::last_error()` to see where the error occurred.
When I remove the row containing NA
demo %>%
select(-id) %>%
group_by(qid, subgroup) %>%
drop_na() %>%
mutate(new_column = ind.oneway.second(mean, sd, N, sig.level = 0.05) %>%
{qf(.95, .[["anova.table"]][["df"]][1], .[["anova.table"]][["df"]][2]) < .[["anova.table"]][["F"]][1]})
I get
# A tibble: 10 x 8
# Groups: qid, subgroup [2]
qid question subgroup name N mean sd new_column
<dbl> <chr> <chr> <chr> <dbl> <dbl> <dbl> <lgl>
1 1 noise course A 11 4 0.77 FALSE
2 1 noise course B 47 3.55 1.16 FALSE
3 1 noise course C 31 3.29 1.24 FALSE
4 1 noise course D 40 3.8 0.85 FALSE
5 1 noise course E 16 3.38 1.09 FALSE
6 1 noise course F 11 3.55 1.13 FALSE
7 1 noise course G 25 4.12 0.73 FALSE
8 1 noise course H 25 3.68 0.85 FALSE
9 1 noise gender f 120 3.65 1.07 FALSE
10 1 noise gender m 93 3.67 0.98 FALSE
Upvotes: 1