Сводный табличный вывод в R?
Я пишу отчет, который требует генерации нескольких сводных таблиц в Excel. Я хотел бы думать, что есть способ сделать это в R, чтобы я мог избежать Excel. Я хотел бы выводить как снимок экрана ниже (имена преподавателей отредактированы). Насколько я могу судить, я мог бы использовать пакет reshape для вычисления совокупных значений, но мне нужно будет делать это несколько раз и каким-то образом получить все данные в правильном порядке. В этот момент я должен просто делать это в Excel. Есть ли у кого-нибудь предложения или рекомендации пакета? Спасибо!
(РЕДАКТИРОВАТЬ)
Данные начинаются как список студентов, их учитель, школа и рост. Затем эти данные агрегируются для получения списка учителей с их средним ростом класса. Обратите внимание, что учителя затем сгруппированы по школе. Самая большая проблема, которую я предвижу делать с R на данный момент, заключается в том, как вы получаете промежуточные и итоговые строки (BSA1 Total, Grand Total и т.д.) Там, поскольку они не являются тем же типом наблюдений, что и другие? Вам просто нужно вручную вычислить их и попытаться получить их в правильном порядке, чтобы они отображались внизу этой группы?
![example]()
Ответы
Ответ 1
Здесь swag для битов вычисления:
set.seed(1)
school <- sample(c("BSA1", "BSA2", "HSA1"), 100, replace=T)
teacher <- sample(c("Tom", "Dick", "Harry"), 100, replace=T)
growth <- rnorm(100, 5, 3)
myDf <- data.frame(school, teacher, growth)
require(reshape2)
aggregate(growth ~ school + teacher, data =myDf, FUN=mean)
myDf.melt <- melt(myDf, measured="growth")
dcast(myDf.melt, school + teacher ~ ., fun.aggregate=mean, margins=c("school", "teacher"))
Я не рассматривал форматирование вывода, а только вычисление. Результирующий кадр данных должен выглядеть следующим образом:
school teacher NA
1 BSA1 Dick 4.663140
2 BSA1 Harry 4.310802
3 BSA1 Tom 5.505247
4 BSA1 (all) 4.670451
5 BSA2 Dick 6.110988
6 BSA2 Harry 5.007221
7 BSA2 Tom 4.337063
8 BSA2 (all) 5.196018
9 HSA1 Dick 4.508610
10 HSA1 Harry 4.890741
11 HSA1 Tom 4.721124
12 HSA1 (all) 4.717335
13 (all) (all) 4.886576
В этом примере используется пакет reshape2 для обработки промежуточных итогов.
Я думаю, что R - правильный инструмент для работы здесь. Я полностью понимаю, что не знаю, как начать этот анализ. Я приехал в R из Excel несколько лет назад, и сначала это может быть сложно. Позвольте мне указать четыре совета, которые помогут вам получить более качественные ответы в Stack Overflow:
1) предоставляют данные, даже если они моделируются: вы можете видеть, что я смоделировал некоторые данные в начале моего ответа. Если бы вы предоставили эту симуляцию, она бы: a) спасла мне время b) получила ответ, который использовал вашу собственную структуру данных, а не тот, о котором я мечтал, и c) другие люди ответили бы. Я часто пропускаю вопросы без каких-либо данных, потому что я устал догадываться о данных, которые им сообщают, что мой ответ засасывается, потому что я догадался.
2) Задайте один ясный вопрос. "Как мне выполнить свою работу" - это не однозначный вопрос. "Как взять данные примера и создать промежуточные итоги в агрегации, как в этом примере, вывод" - это один конкретный вопрос.
3) продолжайте спрашивать! Мы все поправляемся с практикой. Вы пытаетесь сделать больше в R и меньше в Excel, поэтому у вас явно выше среднего интеллекта. Продолжайте использовать R и продолжайте задавать вопросы. Все будет легче во времени.
4) Будьте осторожны с вашими словами, когда вы описываете вещи. Вы говорите в своем отредактированном вопросе, что у вас есть "список" вещей. Список в R представляет собой конкретную структуру данных. Я подозрительно, что у вас действительно есть фрейм данных и использует термин "список" в общем смысле. Это может вызвать некоторую путаницу. Это также иллюстрирует, почему вы хотите предоставить свои собственные данные.
Ответ 2
Использование синтаксических данных JD Long и добавление sd и counts:
library(reshape) # not reshape2
cast(myDf.melt, school + teacher ~ ., margins=TRUE , c(mean, sd, length))
school teacher mean sd length
1 BSA1 Dick 4.663140 3.718773 14
2 BSA1 Harry 4.310802 1.430594 9
3 BSA1 Tom 5.505247 4.045846 4
4 BSA1 (all) 4.670451 3.095980 27
5 BSA2 Dick 6.110988 2.304104 15
6 BSA2 Harry 5.007221 2.908146 9
7 BSA2 Tom 4.337063 2.789244 14
8 BSA2 (all) 5.196018 2.682924 38
9 HSA1 Dick 4.508610 2.946961 11
10 HSA1 Harry 4.890741 2.977305 13
11 HSA1 Tom 4.721124 3.193576 11
12 HSA1 (all) 4.717335 2.950959 35
13 (all) (all) 4.886576 2.873637 100
Ответ 3
Ниже приведены несколько способов генерации этого метода с использованием относительно нового пакета pivottabler.
Раскрытие информации: я автор пакетов.
Для получения дополнительной информации см. страницу пакета CRAN и различные виджеты пакета, доступные на этой странице.
Примеры данных (как указано выше)
set.seed(1)
school <- sample(c("BSA1", "BSA2", "HSA1"), 100, replace=T)
teacher <- sample(c("Tom", "Dick", "Harry"), 100, replace=T)
growth <- rnorm(100, 5, 3)
myDf <- data.frame(school, teacher, growth)
Быстрый вывод сводной таблицы на консоль как обычный текст
library(pivottabler)
# arguments: qhpvt(dataFrame, rows, columns, calculations, ...)
qpvt(myDf, c("school", "teacher"), NULL,
c("Average Growth"="mean(growth)", "Std Dev"="sd(growth)",
"# of Scholars"="n()"),
formats=list("%.1f", "%.1f", "%.0f"))
Выход консоли:
Average Growth Std Dev # of Scholars
BSA1 Dick 4.7 3.7 14
Harry 4.3 1.4 9
Tom 5.5 4.0 4
Total 4.7 3.1 27
BSA2 Dick 6.1 2.3 15
Harry 5.0 2.9 9
Tom 4.3 2.8 14
Total 5.2 2.7 38
HSA1 Dick 4.5 2.9 11
Harry 4.9 3.0 13
Tom 4.7 3.2 11
Total 4.7 3.0 35
Total 4.9 2.9 100
Быстрый вывод сводной таблицы как виджет html
library(pivottabler)
qhpvt(myDf, c("school", "teacher"), NULL,
c("Average Growth"="mean(growth)", "Std Dev"="sd(growth)",
"# of Scholars"="n()"),
formats=list("%.1f", "%.1f", "%.0f"))
Выход HTML-виджета:
![введите описание изображения здесь]()
Создание сводной таблицы с использованием более подробного синтаксиса
У этого есть больше вариантов, например. переименование итогов.
library(pivottabler)
pt <- PivotTable$new()
pt$addData(myDf)
pt$addRowDataGroups("school", totalCaption="(all)")
pt$addRowDataGroups("teacher", totalCaption="(all)")
pt$defineCalculation(calculationName="c1", caption="Average Growth",
summariseExpression="mean(growth)", format="%.1f")
pt$defineCalculation(calculationName="c2", caption="Std Dev",
summariseExpression="sd(growth)", format="%.1f")
pt$defineCalculation(calculationName="c3", caption="# of Scholars",
summariseExpression="n()", format="%.0f")
pt # to output to console as plain text
pt$renderPivot() # to output as a html widget
Выход HTML-виджета:
![введите описание изображения здесь]()
Ответ 4
Извините за автопромоцию, но посмотрите на мой пакет expss.
Код для вывода ниже:
set.seed(1)
school <- sample(c("BSA1", "BSA2", "HSA1"), 100, replace=T)
teacher <- sample(c("Tom", "Dick", "Harry"), 100, replace=T)
growth <- rnorm(100, 5, 3)
myDf <- data.frame(school, teacher, growth)
library(expss)
myDf %>%
# 'tab_cells' - variables on which statistics will be calculated
# "|" is needed to suppress 'growth' in row labels
tab_cells("|" = growth) %>%
# 'tab_cols' - variables for columns. Can be ommited
tab_cols(total(label = "")) %>%
# 'tab_rows' - variables for rows.
tab_rows(school %nest% list(teacher, "(All)"), "|" = "(All)") %>%
# 'method = list' is needed for statistics labels in column
tab_stat_fun("Average Growth" = mean,
"Std Dev" = sd,
"# of scholars" = length,
method = list) %>%
# finalize table
tab_pivot()
Код выше дает объект, унаследованный от data.frame, который может использоваться со стандартными операциями R (подмножество с [
и т.д.). Но для этого объекта существует специальный метод print
. Выход консоли:
| | | Average Growth | Std Dev | # of scholars |
| ----- | ----- | -------------- | ------- | ------------- |
| BSA1 | Dick | 4.7 | 3.7 | 14 |
| | Harry | 4.3 | 1.4 | 9 |
| | Tom | 5.5 | 4.0 | 4 |
| | (All) | 4.7 | 3.1 | 27 |
| BSA2 | Dick | 6.1 | 2.3 | 15 |
| | Harry | 5.0 | 2.9 | 9 |
| | Tom | 4.3 | 2.8 | 14 |
| | (All) | 5.2 | 2.7 | 38 |
| HSA1 | Dick | 4.5 | 2.9 | 11 |
| | Harry | 4.9 | 3.0 | 13 |
| | Tom | 4.7 | 3.2 | 11 |
| | (All) | 4.7 | 3.0 | 35 |
| (All) | | 4.9 | 2.9 | 100 |
Вывод через htmlTable
в knitr, RStudio viewer или Shiny:
![a0fRw.png]()