Кросс-табуляция с n>2 категориями в R: скрыть строки с нулевыми регистрами

Я пытаюсь сделать кросс-табуляцию в R, и ее вывод будет максимально похож на то, что я получу в сводной таблице Excel. Итак, учитывая этот код:

set.seed(2)
df<-data.frame("ministry"=paste("ministry ",sample(1:3,20,replace=T)),"department"=paste("department ",sample(1:3,20,replace=T)),"program"=paste("program ",sample(letters[1:20],20,replace=F)),"budget"=runif(20)*1e6)
library(tables)
library(dplyr)
arrange(df,ministry,department,program)
tabular(ministry*department~((Count=budget)+(Avg=(mean*budget))+(Total=(sum*budget))),data=df)

который дает:

                                 Avg    Total  
 ministry    department    Count budget budget 
 ministry  1 department  1 5     479871 2399356
             department  2 1     770028  770028
             department  3 1     184673  184673
 ministry  2 department  1 2     170818  341637
             department  2 1     183373  183373
             department  3 3     415480 1246440
 ministry  3 department  1 0        NaN       0    <---- LOOK HERE
             department  2 5     680102 3400509
             department  3 2     165118  330235

Как мне получить выходные данные, чтобы скрыть строки с нулевыми частотами? я использую tables::tabular но любой другой пакет хорош для меня (если есть способ, даже косвенный, для вывода в html). Это для генерации HTML или Latex с использованием R Markdown и отображения таблицы с результатами моего скрипта, как в Excel, или как в примере выше, в виде сводной таблицы. Но без лишнего ряда.

Спасибо!

2 ответа

Почему бы просто не использовать dplyr?

df %>%
group_by(ministry, department) %>%
summarise(count = n(),
        avg_budget = mean(budget, na.rm = TRUE),
        tot_budget = sum(budget, na.rm = TRUE))



     ministry    department count avg_budget tot_budget
1 ministry  1 department  1     5   479871.1  2399355.6
2 ministry  1 department  2     1   770027.9   770027.9
3 ministry  1 department  3     1   184673.5   184673.5
4 ministry  2 department  1     2   170818.3   341636.5
5 ministry  2 department  2     1   183373.2   183373.2
6 ministry  2 department  3     3   415479.9  1246439.7
7 ministry  3 department  2     5   680101.8  3400508.8
8 ministry  3 department  3     2   165117.6   330235.3

Хотя я совсем не понимаю, как tabular объект сделан (так как он говорит, что это список, но, похоже, ведет себя как фрейм данных), вы можете выбрать ячейки как обычно, поэтому

> results <-tabular(ministry*department~((Count=budget)+(Avg=(mean*budget))+(Total=(sum*budget))),data=df)
> results[results[,1]!=0,]

                                 Avg    Total  
 ministry    department    Count budget budget 
 ministry  1 department  1 5     479871 2399356
             department  2 1     770028  770028
             department  3 1     184673  184673
 ministry  2 department  1 2     170818  341637
             department  2 1     183373  183373
             department  3 3     415480 1246440
 ministry  3 department  2 5     680102 3400509
             department  3 2     165118  330235

Это решение.

Я только что нашел решение благодаря ответу этого пользователя на другой вопрос G. Grothendieck

Другие вопросы по тегам