问题描述
我想创建一个可以导出为pdf或word文档的表格。是否有任何可用于自动/快速获取表格的软件包?我尝试了数据透视表和table1包,但确实得到了输出,但是格式不完全符合我的要求。
数据:让我们考虑mtcars数据。
func encode2(input: String) -> [(Int,Character)] {
var result = [(Int,Character)]()
input.forEach { char in
if result.last?.1 == char {
result[result.count - 1].0 += 1
} else {
result.append((1,char))
}
}
return result
}
输出:我想按照以下示例在表中创建以上数据
cars mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
以上值不正确。它只是一个例子。我想要以上格式的表格。
当我尝试使用数据透视表包时,
Vs *disp* mpg am_1 am_0 *Total*
0 460 21.0 20 (11%) 0 20 (11%)
120 21.0 8 (9%) 8 (9%) 16 (18%)
151 18.7 2 (2%) 3(1%) 5 (3%)
1 151 12.0 8 (9%) 9 (10%) 17(19%)
424 25.0 118 (10%) 6 (5%) 124 (15%)
我得到以下输出,但是我希望这些值在同一单元格中以计数和百分比表示
解决方法
我会根据您的需求建议两个选项。首先,您需要处理数据:
library(tidyverse)
library(grid)
library(gridExtra)
library(officer)
#Data
data("mtcars")
#Format
S <- mtcars %>% group_by(vs,cyl,am) %>% summarise(N=n()) %>% ungroup() %>%
group_by(vs,cyl) %>% mutate(Total=sum(N),Percentage=100*round(N/Total,3)) %>%
pivot_wider(names_from = am,values_from = c(N,Percentage)) %>%
replace(is.na(.),0) %>%
mutate(N_1=paste0(N_1,' (',paste0(Percentage_1,'%'),')'),N_0=paste0(N_0,paste0(Percentage_0,Total=paste0(Total,'(',paste0(Percentage_1+Percentage_0,')')) %>%
select(vs,N_0,N_1,Total)
您将得到这个(您可以适应所需的内容,这是一个示例):
# A tibble: 5 x 5
# Groups: vs,cyl [5]
vs cyl N_0 N_1 Total
<dbl> <dbl> <chr> <chr> <chr>
1 0 4 0 (0%) 1 (100%) 1(100%)
2 0 6 0 (0%) 3 (100%) 3(100%)
3 0 8 12 (85.7%) 2 (14.3%) 14(100%)
4 1 4 3 (30%) 7 (70%) 10(100%)
5 1 6 4 (100%) 0 (0%) 4(100%)
现在第一个选择是使用grid
和gridExtra
软件包导出为pdf:
#Prepare for export option 1 using grid
myTable <- tableGrob(
S,rows = NULL,theme = ttheme_default(core = list(bg_params = list(fill = "grey99")))
)
#Export to pdf
pdf('Example.pdf',width = 10)
grid.draw(myTable)
dev.off()
您将获得一个.pdf
的图像,如下所示:
第二个选项是officer
软件包:
#Second option with officer package
doc <- read_docx() %>%
body_add_par(value = "My Table",style = "heading 1") %>%
body_add_table(value = S,style = "Table Professional",alignment = "c" )
print(doc,target = "Example.docx")
您最终将获得一个.docx
文档,如下所示:
至少有两种方法可以通过数据透视表程序包解决此问题。
这两种方法都定义了多个计算:
- 第一个计算是基本计数
- 第二个计算将覆盖每个单元格中存在的过滤器,因此只有来自列变量的过滤器才适用于该单元格-这意味着此计算将始终得出列总数。此计算在数据透视表中不可见(已指定visible = FALSE)。
- 第三次计算要么计算列总计的百分比(方法1),要么计算计数和列总计的百分比的串联值(方法2)。
方法1
这使用两个单独的列,其中(IMHO)更易于阅读:
library(pivottabler)
pt <- PivotTable$new()
pt$addData(mtcars)
pt$addColumnDataGroups("am")
pt$addRowDataGroups("vs")
pt$addRowDataGroups("mpg",totalCaption= "Subtotal")
pt$addRowDataGroups("disp",addTotal=FALSE)
# basic calculation
pt$defineCalculation(calculationName="CountVal",caption="V",summariseExpression="n()")
# get column totals
filterOverrides <- PivotFilterOverrides$new(pt,keepOnlyFiltersFor="am")
pt$defineCalculation(calculationName="CountAll",summariseExpression="n()",filters=filterOverrides,visible=FALSE)
# percentage of column calculation total
pt$defineCalculation(calculationName="Percent",caption="%",type="calculation",basedOn=c("CountVal","CountAll"),format="%.1f %%",calculationExpression="values$CountVal/values$CountAll*100")
pt$renderPivot()
方法2
这会将值合并为一列:
library(pivottabler)
pt <- PivotTable$new()
pt$addData(mtcars)
pt$addColumnDataGroups("am")
pt$addRowDataGroups("vs")
pt$addRowDataGroups("mpg",visible=FALSE)
# get column totals
filterOverrides <- PivotFilterOverrides$new(pt,caption="Percent",calculationExpression="paste0(values$CountVal,sprintf('%.1f %%',values$CountVal/values$CountAll*100),')')")
pt$renderPivot()
方法2-更新1
方法2的以下版本显示行组的标题并更改计算值,以便零显示而没有括号。
library(pivottabler)
pt <- PivotTable$new()
pt$addData(mtcars)
pt$addColumnDataGroups("am")
pt$addRowDataGroups("vs",header="vs")
pt$addRowDataGroups("mpg",totalCaption= "Subtotal",header="mpg")
pt$addRowDataGroups("disp",addTotal=FALSE,header="disp")
# basic calculation
pt$defineCalculation(calculationName="CountVal",calculationExpression="ifelse(is.null(values$CountVal)||values$CountVal==0,paste0(values$CountVal,')'))")
pt$renderPivot(showRowGroupHeaders=TRUE)
方法2-更新2
此更改将小计移动到顶部,移除总计在底部,显示不带小数位的百分比。
library(pivottabler)
pt <- PivotTable$new()
pt$addData(mtcars)
pt$addColumnDataGroups("am")
pt$addRowDataGroups("vs",header="vs",addTotal=FALSE)
pt$addRowDataGroups("mpg",header="mpg",totalPosition="before")
pt$addRowDataGroups("disp",sprintf('%.0f %%',')'))")
pt$renderPivot(showRowGroupHeaders=TRUE)
,
我建议使用m = df['type'].eq('A')
df.loc[m,'col1':'col5'] = df.loc[m,'col1':'col5'].gt(2).astype(int)
print (df)
col1 col2 col3 col4 col5 type number
0 0.0 1 1 1.0 0 A one
1 1.0 0 1 1.0 1 A two
2 4.0 4 0 22.0 7 C two
3 1.0 1 1 1.0 1 A one
4 9.0 0 3 6.0 8 B one
5 0.0 0 1 0.0 0 A two
6 6.0 5 7 9.0 9 E two
将表编织到r markdown文件中,如下所示:
knitr::kable
您可以隐藏标题为library(knitr)
library(tidyverse)
kable(mtcars %>% dplyr::select(am,vs,mpg,disp)... )
的在输出PDF中生成表格的代码。您可以对第一个kable参数中的数据执行所有标准数据操作,或者在r markdown设置中进行操作,然后将最后的数据帧作为参数x输入kable。
在r markdown文件中,您可以将文档编织为r studio中“编织”标签下的Word格式的PDF。这就是您的想法吗?