I'm trying to summarise a dataframe using two variables - I basically want to break down variable 1 by variable 2 in order to plot the results in a 100% stacked bar chart.
I have multiple columns of type char and multiple columns of type numeric, which can be split between two main categories that will be used to create the breakdown.
I have tried to use gather
from dplyr
to transform the dataframe to longform, however the output is not what I expect.
variable1_by_variable2 <- function (dataset, variable_1) {
#select variables columns - variable 1 columns are char, variable 2
#columns are numeric
variable_1_columns <- dataset[, data.table::`%like%`(names(dataset), variable_1)]
variable_2_columns <- dataset[, c('e_j', 'e_t', 'e_f', 'e_s', 'e_d', 'e_a')]
#create new dataframe including only relevant columns
df <- cbind(variable_1_columns, emotions_columns)
df[c('e_j', 'e_t', 'e_f', 'e_s', 'e_d', 'e_a')] <-
lapply(df[c('e_j', 'e_t', 'e_f', 'e_s', 'e_d', 'e_a')],
as.numeric)
#transform df to long form
new_df <- tidyr::gather(df, variable_2_columns, count, names(variable_2_columns[1]):names(variable_2_columns)[length(names(variable_2_columns))], factor_key=FALSE)
t_names <- names(variable_1_columns)
#count topics
t_count <- function (x) {
t <- sum(x == TRUE)
}
#group by variable 2 and count
new_df <- new_df %>%
dplyr::group_by(variable_2_columns) %>%
dplyr::summarise_at(t_names, .funs = t_count)
#transform new_df to longform
final_df <- tidyr::gather(new_df, t, volume, names(variable_1_columns[1]):names(variable_1_columns)[length(names(variable_1_columns))], factor_key=FALSE)
final_df <- data.frame(final_df)
return (final_df)
}
This is the dataset I'm using:
structure(list(var_a = c("TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), var_b = c("FALSE",
"FALSE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "FALSE", "FALSE", "FALSE", "FALSE"), var_c = c("FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"
), var_d = c("FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE"), var_e = c("FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"FALSE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), var_f = c("FALSE",
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE",
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), e_j = c(0.5,
NaN, 0, 0.333333333333333, 0.333333333333333, 0.5, 0, 0, 1, 1,
0.666666666666667, NaN, 0, NaN, 0.5, 0.333333333333333, 0.333333333333333,
0, 0, 0, 0, 0.5, 0.333333333333333, 0, 0, 1, 0, 0.333333333333333,
0, NaN, 0.25, 0.5, 0.5, 0, 0, 0.5, 0.333333333333333, 0.5, 0.5
), e_t = c(0.5, NaN, 0, 0.666666666666667, 0.666666666666667,
0.5, 1, 0.333333333333333, 0, 0, 0.333333333333333, NaN, 1, NaN,
0.5, 0.666666666666667, 0.333333333333333, 0.25, 1, 1, 0.333333333333333,
0.5, 0.666666666666667, 1, 1, 0, 1, 0.666666666666667, 0, NaN,
0.25, 0.5, 0.5, 0.4, 0, 0.5, 0.5, 0.5, 0.5), fear = c(0, NaN,
0.5, 0, 0, 0, 0, 0.333333333333333, 0, 0, 0, NaN, 0, NaN, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN, 0, 0, 0, 0.2,
0, 0, 0, 0, 0), e_s = c(0, NaN, 0, 0, 0, 0, 0, 0, 0, 0, 0,
NaN, 0, NaN, 0, 0, 0.166666666666667, 0.5, 0, 0, 0.333333333333333,
0, 0, 0, 0, 0, 0, 0, 0.75, NaN, 0.25, 0, 0, 0.2, 0.5, 0, 0, 0,
0), e_d = c(0, NaN, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN, 0, NaN,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN, 0, 0, 0, 0,
0, 0, 0, 0, 0), e_a = c(0, NaN, 0.5, 0, 0, 0, 0, 0.333333333333333,
0, 0, 0, NaN, 0, NaN, 0, 0, 0.166666666666667, 0.25, 0, 0, 0.333333333333333,
0, 0, 0, 0, 0, 0, 0, 0.25, NaN, 0.25, 0, 0, 0.2, 0.5, 0, 0.166666666666667,
0, 0)), row.names = c(NA, -39L), class = "data.frame")
The desired output would be the following, however when I use gather
the volume figure is the total number of rows and is repeated across all categories. The numeric values would be the average of each variable for a specific category (for example average of 'e_j' where 'a' is TRUE in the dataset)
e_j e_t e_f e_s e_a e_d category
1 0.31 0.54 0.00 0.09 0.05 0.00 a
2 0.28 0.50 0.03 0.09 0.09 0.00 b
3 0.25 0.52 0.01 0.12 0.09 0.00 c
4 0.25 0.51 0.00 0.12 0.10 0.00 d
5 0.25 0.52 0.01 0.12 0.09 0.00 e
6 0.32 0.49 0.00 0.09 0.07 0.00 f
Not sure how you calculated your expected output, but you can try
library(tidyverse)
df %>%
as_tibble() %>%
gather(var, v, -e_j:-e_a) %>%
select(-fear) %>%
filter(v == "TRUE") %>%
group_by(var) %>%
summarise_at(vars(e_j:e_a), mean, na.rm = T)
# A tibble: 6 x 6
var e_j e_t e_s e_d e_a
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 var_a 0.297 0.457 0.0594 0 0.122
2 var_b 0.281 0.502 0.09 0 0.0928
3 var_c 0.250 0.527 0.121 0 0.0929
4 var_d 0.254 0.518 0.123 0 0.0962
5 var_e 0.250 0.527 0.121 0 0.0929
6 var_f 0.324 0.496 0.0964 0 0.0756
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.