【问题标题】:Convert from long wide data fromat to long data format in R with multiple depth headers在具有多个深度标头的 R 中从长宽数据格式转换为长数据格式
【发布时间】:2014-06-07 13:34:12
【问题描述】:

也许这甚至无法完成,因为我的数据格式不正确,但我正在尝试将其从“某种”宽格式转换为长格式。如果我先修改excel中的数据,我知道怎么用melt来做这件事,但是我有很多数据,我希望不必先手动修改。

基本上,我的标题有深度,每列销售都有多个描述符。帐户、品牌、品种和等级(可能还有其他一些,具体取决于具体情况)

            Account
            Brand
            Variety
            Tier
Dates   
1/1/2011    Sales xxx
2/1/2011    Sales xxx

我需要的格式是

Date Account Brand Variety Tier Sales

我不明白如何使用 reshape 或 melt 来转换它。有什么建议,还是我只能自己动手?

编辑

实际数据看起来像这样(更改名称以保护无辜者)

Account   Account A Account A   Account A   Account A   Account B
Brand     Brand A   Brand A         Brand B         Brand B         Brand C
Variety   Cab           Chard           Merlot          Pinot Grigio    Pinot Noir
 Tier     Tier 2    Tier 3          Tier 2          Tier 1          Tier 3
Date                    
6/1/20     35            47              35               28               -   
7/1/2011   12            17              12               12              84               
8/1/2011   -             -               -                -                -   
9/1/2011   7             7           7            7               84 
10/1/2011 28             28              28              28              112 
11/1/2011                                            168 
12/1/2011  7             7           7            7              224 
1/1/2012                 14                              236 

如果我在 excel 中按摩它看起来像这样

    Date    Compilation_Red Compilation_White   Oak_Cab Oak_Chard
1   11/1/2012   351 140 183 190
2   12/1/2012   191 99  120 92
3   1/1/2013    96  56  87  51
4   2/1/2013    30  30  84  61
5   3/1/2013    96  70  100 57
6   4/1/2013    60  38  52  22
7   5/1/2013    12  17  65  49
8   6/1/2013    9   7   28  21
9   7/1/2013    16  13  23  22
10  8/1/2013    26  29  40  33
11  9/1/2013    14  4   30  23
12  10/1/2013   17  4   47  31
13  11/1/2013   23  5   63  35
14  12/1/2013   25  3   70  41
15  1/1/2014    44  1   88  41
16  2/1/2014    28  7   57  43

那我就知道怎么用melt把它变成长格式了

myItem=melt(Account, id.vars="Date", variable.name="Variety", value.name="Sales")

我只是不明白如何处理所有额外的标题,并将它们变成长格式。

另外,我不明白为什么我的表在放入时看起来很好,但在预览中却被混在一起了。

【问题讨论】:

  • 如果您make your question reproducible,您将获得更多帮助,至少发布一些实际数据
  • 请发布更好的数据样本和您正在寻找的确切结果。另外,请向我们展示您迄今为止尝试过的代码。
  • 使用 dput() 让我们自己尝试代码。

标签: r reshape2 import-from-excel melt


【解决方案1】:

希望这种方式对你有帮助。

devtools::install_github("yikeshu0611/onetree")

onetree 是我自己在 github 上的包。有一个函数:reshape_toLong,用于将宽数据转换为长格式。

library(onetree)

您的问题发生在标题上,但是,根据您上面提供的数据,很难识别标题。 如果你有这样的长标题

wide=read_Text("
AccountBrandVarietyTierDate AccountABrandACabTier2 AccountABrandAChardTier3   AccountABrandBMerlotTier2   AccountABrandBPinotGrigioTier1   AccountBBrandCPinotNoirTier3
6/1/20     35            47              35               28               -   
7/1/2011   12            17              12               12              84               
8/1/2011   -             -               -                -                -   
9/1/2011   7             7               7                7               84 
10/1/2011  28            28              28               28              112 
11/1/2011  -             -               -               168                -
12/1/2011  7             7                7               7              224 
1/1/2012   -             14              -              236               -")


colnames(wide)[1]="date" #change the id var to be different

long = reshape_toLong(data = wide,
                       id = "date",
                        j = "newcolumn",
          value.var.prefix = "Account")

head(long,10)

        date         newcolumn Account
1     6/1/20   ABrandACabTier2      35
2   7/1/2011   ABrandACabTier2      12
3   8/1/2011   ABrandACabTier2       -
4   9/1/2011   ABrandACabTier2       7
5  10/1/2011   ABrandACabTier2      28
6  11/1/2011   ABrandACabTier2       -
7  12/1/2011   ABrandACabTier2       7
8   1/1/2012   ABrandACabTier2       -
9     6/1/20 ABrandAChardTier3      47
10  7/1/2011 ABrandAChardTier3      17

然后我们使用 Left、Right、Mid 和 Reverse 函数来处理新列。

long$AccountABC = Left(long$newcolumn,1)
long$Brand = Mid(long$newcolumn,2,6)
long$Tier=Right(long$newcolumn,5)
Variety1= Mid(long$newcolumn,8,60)
Variety2=Mid(Reverse(Variety1),6,60)
long$Variety=Reverse(Variety2)
head(long,20)
        date          newcolumn Account AccountABC  Brand  Tier Variety
1     6/1/20    ABrandACabTier2      35          A BrandA Tier2     Cab
2   7/1/2011    ABrandACabTier2      12          A BrandA Tier2     Cab
3   8/1/2011    ABrandACabTier2       -          A BrandA Tier2     Cab
4   9/1/2011    ABrandACabTier2       7          A BrandA Tier2     Cab
5  10/1/2011    ABrandACabTier2      28          A BrandA Tier2     Cab
6  11/1/2011    ABrandACabTier2       -          A BrandA Tier2     Cab
7  12/1/2011    ABrandACabTier2       7          A BrandA Tier2     Cab
8   1/1/2012    ABrandACabTier2       -          A BrandA Tier2     Cab
9     6/1/20  ABrandAChardTier3      47          A BrandA Tier3   Chard
10  7/1/2011  ABrandAChardTier3      17          A BrandA Tier3   Chard
11  8/1/2011  ABrandAChardTier3       -          A BrandA Tier3   Chard
12  9/1/2011  ABrandAChardTier3       7          A BrandA Tier3   Chard
13 10/1/2011  ABrandAChardTier3      28          A BrandA Tier3   Chard
14 11/1/2011  ABrandAChardTier3       -          A BrandA Tier3   Chard
15 12/1/2011  ABrandAChardTier3       7          A BrandA Tier3   Chard
16  1/1/2012  ABrandAChardTier3      14          A BrandA Tier3   Chard
17    6/1/20 ABrandBMerlotTier2      35          A BrandB Tier2  Merlot
18  7/1/2011 ABrandBMerlotTier2      12          A BrandB Tier2  Merlot
19  8/1/2011 ABrandBMerlotTier2       -          A BrandB Tier2  Merlot
20  9/1/2011 ABrandBMerlotTier2       7          A BrandB Tier2  Merlot

【讨论】:

    【解决方案2】:

    如果你的数据是这样的,那就更简单了。

    wide=read.table(header = FALSE, text = ("
    Account   AccountA AccountA   AccountA   AccountA       AccountB
    Brand     BrandA   BrandA     BrandB     BrandB         BrandC
    Variety   Cab      Chard      Merlot     PinotGrigio    PinotNoir
    Tier      Tier2   Tier3     Tier2        Tier1           Tier3
    6/1/20     35      47          35        28               -   
    7/1/2011   12      17          12        12              84               
    8/1/2011   -       -           -         -                -   
    9/1/2011   7       7           7         7               84 
    10/1/2011  28      28          28        28              112 
    11/1/2011  -       -           -         168              -
    12/1/2011  7       7           7         7               224 
    1/1/2012   -       14          -         236              -
              "))
    

    我们可以将 row1 更改为 row4 作为一个字符串并作为列名处理。

    for (i in 1:ncol(wide)) {
      colnames(wide)[i]=inner_Add_Symbol(wide[1:4,i],"_")
    }
    

    然后我们从第1行删除到第4行,并将列名1改为日期,将作为id处理。

    wide2=wide[-(1:4),]
    colnames(wide2)[1]="date"
    

    关键步骤重塑为长数据

    long=reshape_toLong(data = wide2,
                          id="date",
                          j="newcolumn",
        value.var.prefix = "Account")
    

    拆分此数据框中的列

    head(split_byonecolumn(long,"newcolumn","_",c("AccountABC","Brand","Variety","Tier")))
    
           date          newcolumn Account AccountABC  Brand Variety  Tier
    1    6/1/20 A_BrandA_Cab_Tier2      35          A BrandA     Cab Tier2
    2  7/1/2011 A_BrandA_Cab_Tier2      12          A BrandA     Cab Tier2
    3  8/1/2011 A_BrandA_Cab_Tier2       -          A BrandA     Cab Tier2
    4  9/1/2011 A_BrandA_Cab_Tier2       7          A BrandA     Cab Tier2
    5 10/1/2011 A_BrandA_Cab_Tier2      28          A BrandA     Cab Tier2
    6 11/1/2011 A_BrandA_Cab_Tier2       -          A BrandA     Cab Tier2
    

    【讨论】:

      猜你喜欢
      • 2023-02-25
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 2021-11-16
      相关资源
      最近更新 更多