在R中使用多个深度标头从长宽数据格式转换为长数据格式

时间:2014-04-22 23:25:37

标签: r reshape2 import-from-excel melt

也许这甚至无法完成,因为我的数据格式不正确,但我正试图将其从“种类”宽格式转换为长格式。如果我首先修改excel中的数据,我知道如何使用melt进行此操作,但是我有很多数据,我希望不必先手动修改它。

基本上我的标题有深度,每个销售列都有多个描述符。帐户,品牌,品种和层级(也许还有其他一些,取决于这种情况如何)

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

我需要的格式是

Date Account Brand Variety Tier Sales

我不明白如何使用重塑或融化来转换它。有任何建议,还是我必须手工完成?

修改

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

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

然后我知道如何使用融合将其变成长格式

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

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

此外,我不明白为什么我的桌子看起来很好,当我把它放入,但在预览中被捣碎在一起。

2 个答案:

答案 0 :(得分:0)

希望这种方式对您有所帮助。

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函数处理newcolumn列。

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

答案 1 :(得分:0)

如果您的数据是这样,那就更容易了。

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