Как создать таблицы и линейные диаграммы с подсчетом и процентами с 1 независимой переменной и 3 зависимыми

Я новичок в R, и почему-то кажется, что решить эту проблему несложно. Но, к сожалению, мне не удалось этого сделать после трех дней поиска и экспериментов.

Мои данные находятся в форме, близкой к широкой:

color   agegroup    sex     ses
red     2           Female  A
blue    2           Female  C
green   5           Male    D
red     3           Female  A
red     2           Male    B
blue    1           Female  B
...

Я пытаюсь создать презентабельные таблицы со счетчиками и процентами зависимой переменной (здесь color), организованными по sex, ses и agegroup. Мне нужна одна таблица, организованная по ses и sex для каждого agegroup, со счетчиками рядом с процентами, например:

agegroup:                                  1
sex:                  Female                               Male
ses:        A       B       C       D           A       B       C       D
color:
red         2 1%    0  0%   8 4%    22 11%      16 8%   2   1%  8   4%  3 1.5%
blue        9 4.5%  6  3%   4 2%    2  1%       12 6%   32 16%  14  7%  6   3%
green       4 2%    12 6%   2 1%    8  4%       0  0%   22 11%  40 20%  0   0%

agegroup:                               2
sex:                  Female                               Male
ses:        A       B       C       D           A       B       C       D
color:
red         2 1%    0  0%   8 4%    22 11%      16 8%   2   1%  8   4%  3 1.5%
blue        9 4.5%  6  3%   4 2%    2  1%       12 6%   32 16%  14  7%  6   3%
green       4 2%    12 6%   2 1%    8  4%       0  0%   22 11%  40 20%  0   0%

Я пытался сделать это со всем, от datatables и expss до gmodels, но я просто не могу понять, как получить такой вывод. CrossTables из gmodels подходит ближе всего, но все еще довольно далеко - (1) процентные значения под счетами, (2) Я не могу поместить его sel в sex, (3) Я могу Я не понимаю, как заставить его разделять результаты по генерации, и (4) результат полон черточек, вертикальных черт и пробелов, что делает его перенос в текстовый процессор или электронную таблицу вручную с высокой вероятностью ошибок.

РЕДАКТИРОВАТЬ: я удалил свой второй вопрос (о линейных графиках), потому что ответ на первый вопрос идеален и заслуживает уважения, даже если он не касается второго. Второй вопрос я задам отдельно, как и следовало бы с самого начала.


person Gil Williams    schedule 15.09.2018    source источник
comment
janitor::tabyl, возможно, стоит взглянуть.   -  person Jon Spring    schedule 15.09.2018
comment
Я ценю это предложение. Таблицы с двумя переменными работают нормально (хотя они мне и не нужны). Однако, когда я пытаюсь добавить третью переменную, возникает ошибка, которую я не могу расшифровать (class показывает, что объект, над которым я работаю, является фреймом данных): Ошибка в классе (dat [[1]]) ‹- new_class: добавление фактора класса к недопустимому объекту Дополнительно: Предупреждающие сообщения: 1: В if (col1_class% в% factor) {: условие имеет длину ›1, и будет использоваться только первый элемент 2: В if (new_class% в % factor) {: длина условия ›1 и будет использоваться только первый элемент   -  person Gil Williams    schedule 15.09.2018
comment
Мне нужны четырехсторонние таблицы (т.е. несколько трехсторонних таблиц), а tabyl, похоже, ограничен трехсторонним. По моему примеру, не получается создать презентабельную таблицу.   -  person Gil Williams    schedule 15.09.2018


Ответы (1)


Ближайший результат с пакетом expss:

library(expss)
# generate example data
set.seed(123)
N = 300
df = data.frame(
    color = sample(c("red", "blue", "green"), size = N, replace = TRUE),
    agegroup = sample(1:5, size = N, replace = TRUE),
    sex = sample(c("Male", "Female"), size = N, replace = TRUE),
    ses = sample(c("A", "B", "C", "D"),  size = N, replace = TRUE),
    stringsAsFactors = FALSE
)

# redirect output to RStudio HTML viewer
expss_output_viewer()
res = df %>% 
    tab_cells("|" = color) %>% # dependent variable, "|" used to suppress label
    tab_cols(sex %nest% ses) %>% # column variable
    tab_rows(agegroup) %>% 
    tab_total_row_position("none") %>% # we don't need total
    tab_stat_cases(label = "Cases") %>% # calculate cases
    tab_stat_cpct(label = "%") %>% # calculate percent
    tab_pivot(stat_position = "inside_columns") %>% # finalize table
    make_subheadings(number_of_columns = 2)

# difficult part - add percent sign
for(i in grep("%", colnames(res))){
    res[[i]] = ifelse(trimws(res[[i]])!="", 
                      paste0(round(res[[i]], 1), "%"),
                      res[[i]] 
                      )
}

# additionlly remove stat labels
colnames(res) = gsub("\\|Cases|%", "", colnames(res), perl = TRUE)

res

В RStudio Viewer результат будет в формате HTML (см. Изображение). К сожалению, я не могу проверить, как он будет вставлен в MS Word. введите здесь описание изображения Отказ от ответственности: я являюсь автором пакета expss.

person Gregory Demin    schedule 15.09.2018
comment
Отлично!! Это создает таблицы именно той формы, которая мне была нужна! Огромное спасибо. Два дополнительных вопроса ... Поскольку вставка HTML немного подвержена ошибкам, я хочу вставить простой текст, а затем сделать это вручную. (1) Но если я использую expss_output_raw, заголовки таблиц сглаживаются и чередуются (например, row_labels Female|A Female|A| Female|B Female|B|) вместо того, чтобы иметь sex в первой строке и ses во второй. Как я могу достичь этого второго формата? (2) В agegroup строках я получаю NA <NA> в каждом столбце, когда вся строка должна быть пустой, за исключением метки. Предложения? Спасибо еще раз! - person Gil Williams; 15.09.2018
comment
@GilWilliams Попробуй expss_output_default() - person Gregory Demin; 15.09.2018
comment
@GilWilliams Другой способ - перетащить таблицу в текстовый файл с разделителем табуляции: fwrite(split_table_to_df(res), "table.tab", sep = "\t", col.names = FALSE, quote = FALSE) - person Gregory Demin; 15.09.2018
comment
Вы, сэр, являетесь Джими Хендриксом из R столов. Спасибо еще раз! - person Gil Williams; 15.09.2018
comment
И последнее: построчные комментарии в вашем коде чрезвычайно полезны! Я бы хотел, чтобы они были во всех примерах кода! - person Gil Williams; 15.09.2018
comment
У меня возникла одна проблема - я использую htmlTable на res, а затем сохраняю его. Файлы имеют кодировку UTF-8 на уровне текста (хорошо!), Но когда я открываю их в браузере, мои (многие, многие) символы Unicode искажаются до неузнаваемости. Ни options(expss.fix_encoding = FALSE), ни options(expss.fix_encoding = TRUE) не действуют. Предложения? - person Gil Williams; 16.09.2018
comment
@GilWilliams Как сохранить результат htmlTable? Я не вижу проблем с результатом writeLines(htmlTable(res), "table.html"). - person Gregory Demin; 16.09.2018
comment
Я сохраняю так же, как вы упомянули. Проблемы возникают только тогда, когда есть символы из-за пределов диапазона, в котором перекрываются ASCII и Unicode. Например, áéíóúñ в сценарии R и на панели просмотра RStudio отображается как áéíóúñ, когда полученный HTML-файл открывается в браузере. Однако в исходном коде он выглядит нормально (при просмотре в текстовом редакторе). - person Gil Williams; 16.09.2018
comment
@GilWilliams Похоже, браузер неправильно определяет кодировку вашего файла. Попробуйте вручную изменить кодировку страницы в браузере на UTF-8. Меня устраивает. - person Gregory Demin; 16.09.2018
comment
Глядя на файл, который сохраняет R, на самом деле нет никакой кодировки HTML или символьной информации (файл имеет кодировку UTF-8 на уровне текста, но это, конечно, другое дело). Так что браузеры должны догадываться об этом, а мои ошибаются. Есть ли способ добавить эту информацию? Я думаю, это потребует вставки чего-то вроде <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> после <HEAD>, но htmlTable, похоже, не может этого сделать. - person Gil Williams; 16.09.2018
comment
@GilWilliams Мы можем сделать это с writeLines(paste0('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', htmlTable(res)), "table.html"). - person Gregory Demin; 16.09.2018
comment
Работал как шарм! Большое спасибо за вашу помощь! - person Gil Williams; 17.09.2018