【问题标题】:Creating a reshaped dataframe with a for-loop [duplicate]使用 for 循环创建重塑的数据框 [重复]
【发布时间】:2018-08-29 15:52:53
【问题描述】:

我正在尝试编写一个 for 循环,该循环可以将数据帧重新组织到表中以进行发布,例如在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)) 

我想制作一个表格,在“州”列中列出每个州一次,每年作为标题为“X 年”的行名,每个 X 值在适当的年份下。在这种情况下,它看起来像这样,减去“...”:

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

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

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

PA ....23 ....22

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

【问题讨论】:

  • 试试spread spread(df, YR, X)
  • 这被称为“重塑”,特别是“从长到宽的重塑”。为此,Base R 有一个名为reshape 的函数。其他包如tidyr 具有“更友好”的功能用于相同目的(如tidyr::spread)。

标签: r for-loop reshape


【解决方案1】:

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) 动物园这将为每个州创建一个年度时间序列:

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) 如果我们要生成时间序列,则为每个状态使用一列更有意义,但也可以将状态用作“时间”:

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 已经在问题下的 cmets 中提供了一个 tidyr 解决方案,所以我们只是指出这一点。

【讨论】:

    【解决方案2】:

    你可以试试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
    

    【讨论】:

      【解决方案3】:

      这将为您提供使用 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
      

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

      【讨论】:

      • 谢谢,这是一个简单的方法。
      猜你喜欢
      • 2021-09-03
      • 2019-12-25
      • 1970-01-01
      • 2021-10-06
      • 2014-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多