使用 for-loop 创建重塑数据框

Creating a reshaped dataframe with a for-loop

我正在尝试编写一个 for 循环,它可以将数据帧重组为 table 以供发布,例如在 excel。

这是我的问题的一小部分数据样本:

df <- data.frame(ST = c("NY", "NJ", "PA", "NY", "NJ", "PA"),
             YR = c(2010, 2010, 2010, 2011, 2011, 2011),
             X = c(.25, .24, .23, .24, .23, .22)) 

我想生成一个 table,它在 "State" 列中列出每个州一次,每年作为标题为 "X Year" 的行名称和正确年份下的每个 X 值.在这种情况下,它看起来像这样,减去“...”:

状态 | 2010 流行音乐 | 2011 年流行

纽约.......25 .....................24

新泽西......24.............23

PA .......23 ......................22

我有大约十几年的数据和所有州的数据,所以我可以通过为每年制作一个数据框、重命名列名、绑定列以及消除重复的 ST 列来费力地完成这项工作。但是,我的直觉是有一种更有效的方法可以做到这一点。希望能帮助思考这个问题。谢谢!

你可以试试reshape函数:

df <- data.frame(ST = c("NY", "NJ", "PA", "NY", "NJ", "PA"),
                 YR = c(2010, 2010, 2010, 2011, 2011, 2011),
                 X = c(.25, .24, .23, .24, .23, .22))

reshape(df, timevar = "YR", idvar = "ST", direction = "wide")

  ST X.2010 X.2011
1 NY   0.25   0.24
2 NJ   0.24   0.23
3 PA   0.23   0.22

这将为您提供使用 tidyverse 包所需的结果。

library(tidyr)
library(dplyr)

df %>% 
  mutate(YR = paste(YR, "Pop")) %>% # add Pop behind year for column headers
  rename(State = ST) %>% # rename state column for outcome
  spread(YR, X)

  State 2010 Pop 2011 Pop
1    NJ     0.24     0.23
2    NY     0.25     0.24
3    PA     0.23     0.22

P.S。我也投票结束了这个问题,因为已经有很多问题的答案像 this on。但目前它可能会帮助您解决问题。

1) xtabs 使用 base R 我们得到了一个简短的解决方案,不需要任何 for 循环或包依赖:

xtabs(X ~., df)

给予:

    YR
ST   2010 2011
  NJ 0.24 0.23
  NY 0.25 0.24
  PA 0.23 0.22

2) tapply 这也只使用基础 R:

tapply(df[[3]], df[-3], sum)

给予:

    YR
ST   2010 2011
  NJ 0.24 0.23
  NY 0.25 0.24
  PA 0.23 0.22

3) zoo 这会为每个州创建一个年度时间序列:

library(zoo)
z <- read.zoo(df, index = "YR", split = "ST")

给予:

> z
       NJ   NY   PA
2010 0.24 0.25 0.23
2011 0.23 0.24 0.22

可以使用 fortify.zoo(z) 生成数据框。

创建时间序列可能有助于简单地执行后续操作。例如,这将绘制它:

library(ggplot2)
autoplot(z) + scale_x_continuous(breaks = time(z)) # separate panels
autoplot(z, facet = NULL) + scale_x_continuous(breaks = time(z)) # single panel

3a) 如果我们要生成时间序列,则为每个状态使用一列更有意义,但可以将状态用作 "times":

read.zoo(df, index = "ST", split = "YR", FUN = identity)

给出这个动物园系列,同样可以使用 fortify.zoo.

将其转换为数据框
   2010 2011
NJ 0.24 0.23
NY 0.25 0.24
PA 0.23 0.22

4) tidyr @Dan Y 已经在问题下的评论中提供了一个 tidyr 解决方案,所以我们只是指出来。