Подтвердить что ты не робот

Сводный табличный вывод в R?

Я пишу отчет, который требует генерации нескольких сводных таблиц в Excel. Я хотел бы думать, что есть способ сделать это в R, чтобы я мог избежать Excel. Я хотел бы выводить как снимок экрана ниже (имена преподавателей отредактированы). Насколько я могу судить, я мог бы использовать пакет reshape для вычисления совокупных значений, но мне нужно будет делать это несколько раз и каким-то образом получить все данные в правильном порядке. В этот момент я должен просто делать это в Excel. Есть ли у кого-нибудь предложения или рекомендации пакета? Спасибо!

(РЕДАКТИРОВАТЬ) Данные начинаются как список студентов, их учитель, школа и рост. Затем эти данные агрегируются для получения списка учителей с их средним ростом класса. Обратите внимание, что учителя затем сгруппированы по школе. Самая большая проблема, которую я предвижу делать с R на данный момент, заключается в том, как вы получаете промежуточные и итоговые строки (BSA1 Total, Grand Total и т.д.) Там, поскольку они не являются тем же типом наблюдений, что и другие? Вам просто нужно вручную вычислить их и попытаться получить их в правильном порядке, чтобы они отображались внизу этой группы?

example

4b9b3361

Ответ 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