如何将数据重塑为宽格式?

时间:2011-10-17 09:49:06

标签: r reshape

我有这样的数据集:

structure(list(var1 = c("APE", "APE", "APE", "APE", "APE", "APE", "GIT",
"APE", "APE", "APE", "APE", "APE", "APE", "APE", "GIT"), var2 = c("AVVAL",
"AULASU", "APALA", "AEA", "ATUPVA", "ASATAP", "ADLO", "AKOKU", "AVVAL",
"AULASU", "APALA", "AEA", "ATUPVA", "ASATAP", "ADLO"), var3 = c(NA,
NA, 1L, 101L, 17122009L, 1L, NA, 684L, NA, NA, 1L, 10L, 17122L,
1L, NA)), .Names = c("var1", "var2", "var3"), row.names = c(NA,
15L), class = "data.frame")

如何将此数据重新整理为宽幅?我试过这个

reshape(h, idvar="var2", v.names="var3", timevar="var1", direction="wide")

但它没有给我一个正确的结果。正确的结果是:

  var1 ADLO AEA AKOKU APALA ASATAP   ATUPVA AULASU AVVAL
1  APE  NaN 101   NA      1      1 17122009     NA    NA
2  APE  NaN  10   684     1      1    17122     NA    NA
3  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN
4  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN

2 个答案:

答案 0 :(得分:3)

被修改

我能达到预期结果的唯一方法是在data.frame中添加一个新列。在我看来,有一些隐含的数据信息未包含在数据中。换句话说,必须有某种分组变量将某些记录标识为属于一起。

由于我不能再猜测这些信息是什么,在我的回答中我将假设每次出现GIT都标志着记录的结束:

x <- grep("GIT", h$var1)
h$rec <- rep(seq_along(x), times=c(x[1], diff(x)))

library(reshape2)
mh <- melt(h, measure.vars="var3")
cast(mh, rec+var1~var2, id.var="rec", measure.var="value", fun.aggregate=mean)

  rec var1 ADLO AEA AKOKU APALA ASATAP   ATUPVA AULASU AVVAL
1   1  APE  NaN  10   NaN     1      1 17122009     NA    NA
2   1  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN
3   2  APE  NaN  10   684     1      1 17122009     NA    NA
4   2  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   Na

原始答案

我发现包reshape2比内置reshape函数更容易理解。该软件包提供两个功能:

  • melt制作广data.frame
  • cast制作高data.frame

在您的情况下,您需要cast

library(reshape2)
cast(h, var1~var2, value="var3", fun.aggregate=mean)

  var1 ADLO AEA AKOKU APALA ASATAP   ATUPVA AULASU AVVAL
1  APE  NaN  10   684     1      1 17122009     NA    NA
2  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN

答案 1 :(得分:0)

由于GIT的含义,我添加了一个新变量:

 dat$id <- cumsum(dat$var1=='GIT')

首先我做聚合:

datMean <- aggregate(var3 ~ var2 * id, data=dat, FUN=mean)

> datMean
    var2 id     var3
1    AEA  0      101
2  APALA  0        1
3 ASATAP  0        1
4 ATUPVA  0 17122009
5    AEA  1       10
6  AKOKU  1      684
7  APALA  1        1
8 ASATAP  1        1
9 ATUPVA  1    17122

然后从长到宽的转换:

datWide <- reshape(datMean, direction='wide', idvar='id', timevar='var2')

> datWide
  id var3.AEA var3.APALA var3.ASATAP var3.ATUPVA var3.AKOKU
1  0      101          1           1    17122009         NA
5  1       10          1           1       17122        684