Кросс-табуляция с 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