在R中从数据框创建交叉表格

3

I have a data frame like this:

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)

我希望将它转换成像这样的东西:

enter image description here

我尝试使用tables包,但没有成功。有人知道如何实现吗?

编辑:输出可以是LaTeX或文本形式。


也许可以使用 library(data.table);dcast(setDT(df), Variable ~ Country, value.var = c('Month', 'Quarter', 'Year')) 进行编程。 - akrun
2个回答

2
我们可以在使用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 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'会创建LaTeX输出。
kable(dt, 'latex') %>%
   kable_styling('striped') %>% 
   add_header_above(c(' ' = 1, 'CA' = 3, 'US' = 3))

- LaTeX 输出
\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}

0

在 R 中,您无法像在 Excel 中那样合并 data.frame 的单元格,但您可以组合Country和period列。下面是使用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的表格,可以使用tables包中的一行代码来完成:

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使用其独特的表达式来生成表格式:

  • ~将行表达式与列表达式分开。我正在显示Variable的行。

  • *表示您正在将一个列嵌套到另一个列中。在这种情况下,我正在将Month:Year列嵌套在Country中。

  • identity指定在每个单元格中显示实际值。

  • Heading用字符串替换下一个项目的标题。在这种情况下,我将"Country""identity"替换为空白。

要输出为latex,可以使用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$ & $2.152$ & $3.854$ & $-0.9456$ & $3.764$ & $1.432$ \\
Interest rate  & $\phantom{-}1.3974$ & $1.820$ & $3.340$ & $\phantom{-}0.4520$ & $1.734$ & $3.962$ \\
Unemployment  & $-0.2303$ & $3.377$ & $3.419$ & $-0.6652$ & $2.486$ & $2.739$ \\
\hline 
\end{tabular}

enter image description here


非常感谢您的帮助。然而,我需要的数据框或表格与图中显示的完全相同。我看到tables包在汇总统计方面做了类似的事情,但是我无法使用我的数据得到相同的结果。 - Renato Leripio
@RenatoLeripio 这个表格能否生成取决于您是否希望输出可以操作。您想要一个 data.frame 作为输出表格,还是只需要一个文本形式的表格,以便您可以复制和粘贴? - acylam
实际上,我需要那个表格用于报告文档。因此,输出可以是LaTeX格式或文本格式。 - Renato Leripio
@RenatoLeripio 你应该在你的问题中加入这个细节。请看我的更新,了解如何使用“tables”包创建表格。 - acylam
1
是的,你说得对。我已经更新了问题。感谢你的帮助。谢谢! - Renato Leripio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接