2016-09-03 7 views
6

Я часто нахожу, что вычисляю сводную статистику в R, используя dplyr, затем записывая результат в csv и загружая его в Tableau для создания таблицы, потому что таблицы Tableo настолько просты и легки. Я бы скорее сгенерировал таблицы непосредственно в R.Табличная таблица сгруппирована в R для уценки

Есть ли простое решение для сгруппированных таблиц в R?

Это очень легко генерировать данные, которые я хотел бы:

library(tidyr) 
library(dplyr) 

summary_table <- iris %>% 
    gather(measure, value, -Species) %>% 
    separate(measure, into=c("attribute", "dimension")) %>% 
    group_by(Species, attribute, dimension) %>% 
    summarise(mean=mean(value)) 

summary_table 

Source: local data frame [12 x 4] 
Groups: Species, attribute [?] 

     Species attribute dimension mean 
     <fctr>  <chr>  <chr> <dbl> 
1  setosa  Petal Length 1.462 
2  setosa  Petal  Width 0.246 
3  setosa  Sepal Length 5.006 
4  setosa  Sepal  Width 3.428 
5 versicolor  Petal Length 4.260 
6 versicolor  Petal  Width 1.326 
7 versicolor  Sepal Length 5.936 
8 versicolor  Sepal  Width 2.770 
9 virginica  Petal Length 5.552 
10 virginica  Petal  Width 2.026 
11 virginica  Sepal Length 6.588 
12 virginica  Sepal  Width 2.974 

Теперь я хотел бы представить это как:

enter image description here

Я хотел бы попробовать несколько различных способы организации, поэтому я хотел бы иметь возможность легко группировать строки, а не столбцы

grouped rows

Основные особенности сгруппированные строки версии являются:

  • Группировка переменная находится на левой стороне, в отдельной колонке, а не в отдельной строке, в клетке, которая охватывает все строки
  • Горизонтальные клеток границы на уровне группы

Я новичок в rmarkdown, но конечной целью является его получение в html-документе.

Возможно ли это?

+0

Вы могли бы рассмотреть делать агрегирование по своему усмотрению, а также. Я попробовал 'aggregate (x = iris [, colnames (iris)] [colnames (iris)! =" Species "]], by = list (iris $ Speces), FUN = function (y) {ifelse (is.numeric (y), mean (y), NA)} ) 'для начала. – nilsole

ответ

4

Ниже приведены способы создания каждой из таблиц с использованием пакета htmlTable. Я не был уверен, как добавить горизонтальные линии между видами, но я добавил оттенок зебры.

Вот документ:

--- 
title: "<h3>Untitled</h3>" 
author: "Author" 
date: "September 3, 2016" 
output: html_document 
--- 

```{r setup, include=FALSE} 
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE) 
``` 

```{r} 
library(tidyr) 
library(dplyr) 
library(reshape2) 
library(htmlTable) 
``` 

```{r} 
st = iris %>% 
    gather(measure, value, -Species) %>% 
    separate(measure, into=c("attribute", "dimension")) %>% 
    group_by(Species, attribute, dimension) %>% 
    summarise(mean=mean(value)) %>% 
    spread(dimension, mean) 

# Keep only first value of outer grouping column 
st = st %>% 
    group_by(Species) %>% 
    mutate(count=1:n()) %>% 
    ungroup %>% 
    mutate(Species = ifelse(count==1, as.character(Species), NA)) %>% 
    select(-count) 

# Remove names of grouping columns 
names(st)[1:2] = "" 

# Round numeric columns to two decimal places 
st[,sapply(st,is.numeric)] = sapply(st[,sapply(st,is.numeric)], function(x) sprintf("%1.2f",x)) 

htmlTable(st, rnames=FALSE, align="llrr", align.header="llrr", 
      col.rgroup = rep(c("none", "gray93"), each=2), 
      css.cell = c("padding-left: 0em","padding-left: 1em",rep("padding-left: 2em",2))) 
``` 
```{r} 
# Another option 
htmlTable(st[,-1], rnames=FALSE, align="llrr", align.header="lrr", 
      n.rgroup=rep(2,3), 
      rgroup=rep(unique(iris$Species),2), 
      #col.rgroup = c("none","gray93"), # If you want to add alternating shading 
      css.cell=c("padding-left: 0.5em","padding-left: 4em","padding-left: 1.5em")) 
``` 

```{r} 
st = iris %>% 
    melt(id.var="Species") %>% 
    group_by(Species, variable) %>% 
    summarise(mean=mean(value)) %>% 
    dcast(Species ~ variable) 
names(st)[1] = "" 

# Round numeric columns to two decimal places 
st[,sapply(st,is.numeric)] = sapply(st[,sapply(st,is.numeric)], function(x) sprintf("%1.2f",x)) 

# Set up grouping columns and column names 
group_col = gsub("(.*)\\..*", "\\1", names(st)) 
group_col = factor(group_col, levels=unique(group_col)) 
names(st) = gsub(".*\\.", "", names(st)) 

htmlTable(st, rnames=FALSE, align="lrrrr", 
      align.header="lrrrr", 
      cgroup=unique(group_col), n.cgroup=unclass(table(group_col)), 
      css.cell = c("padding-left: 0em","padding-left: 1.5em", rep("padding-left: 2em",3))) 
``` 

Вот результат:

enter image description here