【问题标题】:Pivot Table-like Output in R?R中的数据透视表输出?
【发布时间】:2011-10-03 18:29:32
【问题描述】:

我正在编写一份需要在 Excel 中生成多个数据透视表的报告。我想在 R 中有一种方法可以做到这一点,这样我就可以避免使用 Excel。我想要如下截图所示的输出(教师姓名已编辑)。据我所知,我可以使用 reshape 包来计算聚合值,但我需要多次这样做,并以某种方式以正确的顺序获取所有数据。那时,我应该只在 Excel 中进行操作。有没有人有任何建议或包装推荐?谢谢!

(编辑) 数据以学生、他们的老师、学校和成长的列表开始。然后汇总这些数据以获得教师的平均班级增长列表。请注意,教师随后按学校分组。到目前为止,我预见到使用 R 执行此操作的最大问题是,您如何获得小计和总行(BSA1 Total、Grand Total 等),因为它们与其他观察类型不同?您是否只需要手动计算它们并尝试以正确的顺序将它们显示在该组的底部?


(来源:imgh.us

【问题讨论】:

  • 我认为现在的问题太模糊,无法在网站上合理回答。我只能说:如果您还不知道,请学习乳胶,看看这个问题:stackoverflow.com/questions/5465314/… 并使用例如plyrreshapecast 等基本函数以正确的格式获取数据帧。在 R 中获得输出很容易,但您会以文本格式获得。布局应该在别处完成。
  • 您应该查看 R 数据框。
  • 在 R 中当然有很多简单的方法可以做到这一点,但如果你能提供数据的开头以及你想要的结果会更好更适用的代码。
  • 似乎订购有问题,但你没有说它是什么。有什么问题?
  • 感谢大家的cmets。请阅读我对问题的编辑。

标签: r pivot-table reshape


【解决方案1】:

这是计算位的一个赃物:

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 是适合这里工作的工具。我完全可以理解不确定如何开始进行此分析。几年前我从 Excel 来到 R,一开始可能很难理解。让我指出四个专业提示,以帮助您在 Stack Overflow 中获得更好的答案:

1) 提供数据,即使是模拟的:你可以看到我在回答的开头模拟了一些数据。如果您提供了该模拟,它将 a) 节省我的时间 b) 为您提供使用您自己的数据结构的答案,而不是我梦想的答案 c) 其他人会回答。我经常跳过没有数据的问题,因为我已经厌倦了猜测他们被告知的数据我的答案很糟糕,因为我猜错了。

2) 提出一个明确的问题。 “我如何做我的工作”不是一个明确的问题。 “我如何获取此示例数据并像此示例输出一样在聚合中创建小计”是一个特定的问题。

3) 继续提问!我们都会通过练习变得更好。您正在尝试在 R 中做更多的事情,而在 Excel 中做的事情更少,因此您显然具有高于平均水平的智力。继续使用 R 并继续提问。一切都会随着时间变得更容易。

4) 描述事物时要小心措辞。您在已编辑的问题中说,您有一个“清单”。 R中的列表是一种特定的数据结构。我怀疑您实际上有一个数据框,并且在一般意义上使用了“列表”一词。这可能会造成一些混乱。它还说明了您为什么要提供自己的数据。

【讨论】:

  • 谢谢!非常有帮助的答案。
  • 如果您要进行格式化,您会推荐使用 xtable 和 Sweave 吗?或者你推荐的其他东西?再次感谢您。
【解决方案2】:

使用京东龙的模拟数据,加上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

【讨论】:

  • 很好的插图。我变得懒惰了,只是故意的:)
  • 我认为使用 dcast::reshape2 应该很容易,但无法让它工作,所以我恢复为 cast::reshape。
  • 哦...有趣。我也不能在 reshape2 中做到这一点。
  • Hadley 说 reshape2 中删除了多功能聚合以使其更快:twitter.com/#!/hadleywickham/status/90859907947044864
  • 哇,惊人的答案。哈德利是神!
【解决方案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 小部件输出:

【讨论】:

  • 我已经使用这种“快速数据透视表输出到控制台作为纯文本”方法来创建数据透视表。有没有办法将输出保存在数据框中。我会收到以下错误“无法将类'c(“数据透视表”,“R6”)'强制转换为data.frame”
【解决方案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 |

在 knitr、RStudio 查看器或 Shiny 中通过 htmlTable 输出:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多