从 R 中的数据框创建交叉表 table
Creating a cross-tabulated table from data frame in R
我有一个这样的数据框:
df <- data.frame(Country = rep(c("US","CA"),each=3),
Variable = c("Inflation","Unemployment","Interest rate"),
Month = rnorm(6), Quarter = rnorm(6)+2, Year=rnorm(6)+3)
我想把它改造成这样的东西:
我已经尝试了表格包,但没有成功。有没有人知道如何实现这一点?
编辑:输出可以是 LaTeX 或文本格式。
您不能像在 excel 中那样合并 R 中的 data.frame
单元格,但可以合并 Country
和句点列。这是 dplyr
+ tidyr
:
的解决方案
library(dplyr)
library(tidyr)
df %>%
gather(var, value, Month:Year) %>%
unite("var", Country, var) %>%
spread(var, value)
结果:
Variable CA_Month CA_Quarter CA_Year US_Month US_Quarter US_Year
1 Inflation 0.2760235 1.758310 4.233976 -0.4321298 3.6232025 5.149919
2 Interest rate -0.5208693 1.227022 3.412022 1.2283928 3.6858872 3.495870
3 Unemployment -1.0489755 1.531800 3.634362 1.6898725 0.9299318 1.665646
要实际创建一个合并了 Country
的 table(用于报告),以下是使用 tables
包对 one-liner 进行操作的方法:
library(tables)
tabular(Variable ~ Heading()*Country*Heading()*identity*(Month + Quarter + Year), data=df)
结果:
CA US
Variable Month Quarter Year Month Quarter Year
Inflation 0.5269 2.152 3.854 -0.9456 3.764 1.432
Interest rate 1.3974 1.820 3.340 0.4520 1.734 3.962
Unemployment -0.2303 3.377 3.419 -0.6652 2.486 2.739
tabular
使用其独特的表达式生成 table 格式:
~
将行和列的表达式分开。我正在显示 Variable
.
的行
*
表示您将一列嵌套到另一列中。在这种情况下,我将 Month:Year
列嵌套在 Country
.
中
identity
指定您在每个单元格中显示实际值。
Heading
用字符串替换下一项的标题。在这种情况下,我将 "Country"
和 "identity"
替换为空白。
要输出为乳胶,您可以使用 latex
函数包装整个表达式:
latex(tabular(Variable ~ Heading()*Country*Heading()*identity*(Month + Quarter + Year), data=df))
结果:
\begin{tabular}{lcccccc}
\hline
& \multicolumn{6}{c}{Country} \
& \multicolumn{3}{c}{CA} & \multicolumn{3}{c}{US} \
Variable & Month & Quarter & Year & Month & Quarter & \multicolumn{1}{c}{Year} \
\hline
Inflation & $\phantom{-}0.5269$ & .152$ & .854$ & $-0.9456$ & .764$ & .432$ \
Interest rate & $\phantom{-}1.3974$ & .820$ & .340$ & $\phantom{-}0.4520$ & .734$ & .962$ \
Unemployment & $-0.2303$ & .377$ & .419$ & $-0.6652$ & .486$ & .739$ \
\hline
\end{tabular}
我们可以在 data.table
重塑后尝试 knitr
的 kable
library(data.table)
library(knitr)
library(kableExtra)
dt <- dcast(setDT(df), Variable ~ Country, value.var = c('Month', 'Quarter', 'Year'))
nm1 <- names(dt)
nm2 <- c(" ", unique(sub(".*_", "", nm1)[-1]))
setnames(dt, sub("_.*", "", nm1))
setcolorder(dt, order(ave(seq_along(dt), names(dt), FUN = seq_along)))
kable(dt, 'html') %>%
kable_styling('striped') %>%
add_header_above(c(' ' = 1, 'CA' = 3, 'US' = 3))
- 'html'table输出
<table class="table table-striped" style="margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th style="border-bottom:hidden" colspan="1"></th>
<th style="text-align:center; border-bottom:hidden; padding-bottom:0; padding-left:3px;padding-right:3px;" colspan="3"><div style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">CA</div></th>
<th style="text-align:center; border-bottom:hidden; padding-bottom:0; padding-left:3px;padding-right:3px;" colspan="3"><div style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">US</div></th>
</tr>
<tr>
<th style="text-align:left;"> Variable </th>
<th style="text-align:right;"> Month </th>
<th style="text-align:right;"> Quarter </th>
<th style="text-align:right;"> Year </th>
<th style="text-align:right;"> Month </th>
<th style="text-align:right;"> Quarter </th>
<th style="text-align:right;"> Year </th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;"> Inflation </td>
<td style="text-align:right;"> -0.5836272 </td>
<td style="text-align:right;"> 2.0023119 </td>
<td style="text-align:right;"> 2.530939 </td>
<td style="text-align:right;"> -0.5458808 </td>
<td style="text-align:right;"> 2.444585 </td>
<td style="text-align:right;"> 2.237786 </td>
</tr>
<tr>
<td style="text-align:left;"> Interest rate </td>
<td style="text-align:right;"> 0.2660220 </td>
<td style="text-align:right;"> 2.5982691 </td>
<td style="text-align:right;"> 4.536252 </td>
<td style="text-align:right;"> 0.4196231 </td>
<td style="text-align:right;"> 1.151630 </td>
<td style="text-align:right;"> 3.332244 </td>
</tr>
<tr>
<td style="text-align:left;"> Unemployment </td>
<td style="text-align:right;"> 0.8474600 </td>
<td style="text-align:right;"> 0.6830919 </td>
<td style="text-align:right;"> 2.665013 </td>
<td style="text-align:right;"> 0.5365853 </td>
<td style="text-align:right;"> 1.533505 </td>
<td style="text-align:right;"> 1.570910 </td>
</tr>
</tbody>
请注意,将 'html'
替换为 'latex'
会创建乳胶输出
kable(dt, 'latex') %>%
kable_styling('striped') %>%
add_header_above(c(' ' = 1, 'CA' = 3, 'US' = 3))
-乳胶输出
\begin{table}[H]
\centering
\begin{tabular}{l|r|r|r|r|r|r}
\hline
\multicolumn{1}{c|}{ } & \multicolumn{3}{|c|}{CA} & \multicolumn{3}{|c}{US} \
\cline{2-4} \cline{5-7}
Variable & Month & Quarter & Year & Month & Quarter & Year\
\hline
Inflation & -0.5836272 & 2.0023119 & 2.530939 & -0.5458808 & 2.444585 & 2.237786\
\hline
Interest rate & 0.2660220 & 2.5982691 & 4.536252 & 0.4196231 & 1.151630 & 3.332244\
\hline
Unemployment & 0.8474600 & 0.6830919 & 2.665013 & 0.5365853 & 1.533505 & 1.570910\
\hline
\end{tabular}
\end{table}
我有一个这样的数据框:
df <- data.frame(Country = rep(c("US","CA"),each=3),
Variable = c("Inflation","Unemployment","Interest rate"),
Month = rnorm(6), Quarter = rnorm(6)+2, Year=rnorm(6)+3)
我想把它改造成这样的东西:
我已经尝试了表格包,但没有成功。有没有人知道如何实现这一点?
编辑:输出可以是 LaTeX 或文本格式。
您不能像在 excel 中那样合并 R 中的 data.frame
单元格,但可以合并 Country
和句点列。这是 dplyr
+ tidyr
:
library(dplyr)
library(tidyr)
df %>%
gather(var, value, Month:Year) %>%
unite("var", Country, var) %>%
spread(var, value)
结果:
Variable CA_Month CA_Quarter CA_Year US_Month US_Quarter US_Year
1 Inflation 0.2760235 1.758310 4.233976 -0.4321298 3.6232025 5.149919
2 Interest rate -0.5208693 1.227022 3.412022 1.2283928 3.6858872 3.495870
3 Unemployment -1.0489755 1.531800 3.634362 1.6898725 0.9299318 1.665646
要实际创建一个合并了 Country
的 table(用于报告),以下是使用 tables
包对 one-liner 进行操作的方法:
library(tables)
tabular(Variable ~ Heading()*Country*Heading()*identity*(Month + Quarter + Year), data=df)
结果:
CA US
Variable Month Quarter Year Month Quarter Year
Inflation 0.5269 2.152 3.854 -0.9456 3.764 1.432
Interest rate 1.3974 1.820 3.340 0.4520 1.734 3.962
Unemployment -0.2303 3.377 3.419 -0.6652 2.486 2.739
tabular
使用其独特的表达式生成 table 格式:
~
将行和列的表达式分开。我正在显示Variable
. 的行
*
表示您将一列嵌套到另一列中。在这种情况下,我将Month:Year
列嵌套在Country
. 中
identity
指定您在每个单元格中显示实际值。Heading
用字符串替换下一项的标题。在这种情况下,我将"Country"
和"identity"
替换为空白。
要输出为乳胶,您可以使用 latex
函数包装整个表达式:
latex(tabular(Variable ~ Heading()*Country*Heading()*identity*(Month + Quarter + Year), data=df))
结果:
\begin{tabular}{lcccccc}
\hline
& \multicolumn{6}{c}{Country} \
& \multicolumn{3}{c}{CA} & \multicolumn{3}{c}{US} \
Variable & Month & Quarter & Year & Month & Quarter & \multicolumn{1}{c}{Year} \
\hline
Inflation & $\phantom{-}0.5269$ & .152$ & .854$ & $-0.9456$ & .764$ & .432$ \
Interest rate & $\phantom{-}1.3974$ & .820$ & .340$ & $\phantom{-}0.4520$ & .734$ & .962$ \
Unemployment & $-0.2303$ & .377$ & .419$ & $-0.6652$ & .486$ & .739$ \
\hline
\end{tabular}
我们可以在 data.table
knitr
的 kable
library(data.table)
library(knitr)
library(kableExtra)
dt <- dcast(setDT(df), Variable ~ Country, value.var = c('Month', 'Quarter', 'Year'))
nm1 <- names(dt)
nm2 <- c(" ", unique(sub(".*_", "", nm1)[-1]))
setnames(dt, sub("_.*", "", nm1))
setcolorder(dt, order(ave(seq_along(dt), names(dt), FUN = seq_along)))
kable(dt, 'html') %>%
kable_styling('striped') %>%
add_header_above(c(' ' = 1, 'CA' = 3, 'US' = 3))
- 'html'table输出
<table class="table table-striped" style="margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th style="border-bottom:hidden" colspan="1"></th>
<th style="text-align:center; border-bottom:hidden; padding-bottom:0; padding-left:3px;padding-right:3px;" colspan="3"><div style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">CA</div></th>
<th style="text-align:center; border-bottom:hidden; padding-bottom:0; padding-left:3px;padding-right:3px;" colspan="3"><div style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">US</div></th>
</tr>
<tr>
<th style="text-align:left;"> Variable </th>
<th style="text-align:right;"> Month </th>
<th style="text-align:right;"> Quarter </th>
<th style="text-align:right;"> Year </th>
<th style="text-align:right;"> Month </th>
<th style="text-align:right;"> Quarter </th>
<th style="text-align:right;"> Year </th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;"> Inflation </td>
<td style="text-align:right;"> -0.5836272 </td>
<td style="text-align:right;"> 2.0023119 </td>
<td style="text-align:right;"> 2.530939 </td>
<td style="text-align:right;"> -0.5458808 </td>
<td style="text-align:right;"> 2.444585 </td>
<td style="text-align:right;"> 2.237786 </td>
</tr>
<tr>
<td style="text-align:left;"> Interest rate </td>
<td style="text-align:right;"> 0.2660220 </td>
<td style="text-align:right;"> 2.5982691 </td>
<td style="text-align:right;"> 4.536252 </td>
<td style="text-align:right;"> 0.4196231 </td>
<td style="text-align:right;"> 1.151630 </td>
<td style="text-align:right;"> 3.332244 </td>
</tr>
<tr>
<td style="text-align:left;"> Unemployment </td>
<td style="text-align:right;"> 0.8474600 </td>
<td style="text-align:right;"> 0.6830919 </td>
<td style="text-align:right;"> 2.665013 </td>
<td style="text-align:right;"> 0.5365853 </td>
<td style="text-align:right;"> 1.533505 </td>
<td style="text-align:right;"> 1.570910 </td>
</tr>
</tbody>
请注意,将 'html'
替换为 'latex'
会创建乳胶输出
kable(dt, 'latex') %>%
kable_styling('striped') %>%
add_header_above(c(' ' = 1, 'CA' = 3, 'US' = 3))
-乳胶输出
\begin{table}[H]
\centering
\begin{tabular}{l|r|r|r|r|r|r}
\hline
\multicolumn{1}{c|}{ } & \multicolumn{3}{|c|}{CA} & \multicolumn{3}{|c}{US} \
\cline{2-4} \cline{5-7}
Variable & Month & Quarter & Year & Month & Quarter & Year\
\hline
Inflation & -0.5836272 & 2.0023119 & 2.530939 & -0.5458808 & 2.444585 & 2.237786\
\hline
Interest rate & 0.2660220 & 2.5982691 & 4.536252 & 0.4196231 & 1.151630 & 3.332244\
\hline
Unemployment & 0.8474600 & 0.6830919 & 2.665013 & 0.5365853 & 1.533505 & 1.570910\
\hline
\end{tabular}
\end{table}