我正在撰写一份报告,要求在Excel中生成多个数据透视表。我想有一种方法可以在R中执行此操作,以便我可以避免使用Excel。我想输出如下面的截图(教师姓名编辑)。据我所知,我可以使用reshape包来计算聚合值,但我需要多次这样做,并以某种方式以正确的顺序获取所有数据。那时,我应该在Excel中完成它。有没有人有任何建议或包装建议?谢谢!
(编辑) 数据从学生,他们的老师,学校和成长列表开始。然后汇总这些数据以获得具有平均班级增长的教师列表。请注意,然后老师按学校分组。我预见到目前为止这个问题最大的问题是你如何获得小计和总行(BSA1总计,总计等),因为它们与其他行不同?您是否只需手动计算它们并尝试以正确的顺序获取它们,以便它们出现在该组的底部?
答案 0 :(得分:19)
这是对计算位的唠叨:
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中的列表是特定的数据结构。我怀疑你实际上有一个数据框,并且在一般意义上使用术语“列表”。这可能会造成一些混乱。它还说明了您希望提供自己的数据的原因。
答案 1 :(得分:10)
使用JD Long的模拟数据,并添加sd和计数:
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
答案 2 :(得分:1)
以下是使用相对较新的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 Widget输出:
使用更详细的语法生成数据透视表
这有更多选择,例如重命名总数。
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 Widget输出:
答案 3 :(得分:0)
对于autopromotion感到抱歉,但请查看我的资料包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 viewer或Shiny中通过htmlTable
输出: