使用R reshape函数将宽数据帧转换为长数据帧,具有三个重复级别

时间:2017-10-03 16:19:55

标签: r reshape

我一直在努力使用R reshape功能,并且仍然希望一直使用它,因为它是R-core。我偶然发现了像这样的广泛数据框架这个问题

dw <- read.table(header=T, text='
 sbj A.f1.avg A.f1.sd A.f2.avg A.f2.sd B.f1.avg B.f1.sd B.f2.avg B.f2.sd
   A       10       6       50      10       10       6       50      10  
   B       12       5       70      11       12       5       70      11  
   C       20       7       20      8        20       7       20      8   
   D       22       8       22      9        22       8       22      9   
 ')    

我希望得到这样的结果:

sbj AB  f   var res
A   A   f1  avg 10
B   A   f1  avg 12
C   A   f1  avg 20
D   A   f1  avg 22
A   A   f1  sd  6
B   A   f1  sd  5
C   A   f1  sd  7
D   A   f1  sd  8
A   A   f2  avg 50
B   A   f2  avg 70
C   A   f2  avg 20
D   A   f2  avg 22
A   A   f2  sd  10
B   A   f2  sd  11
C   A   f2  sd  8
D   A   f2  sd  9
A   B   f1  avg 10
B   B   f1  avg 12
C   B   f1  avg 20
D   B   f1  avg 22
A   B   f1  sd  6
B   B   f1  sd  5
C   B   f1  sd  7
D   B   f1  sd  8
A   B   f2  avg 50
B   B   f2  avg 70
C   B   f2  avg 20
D   B   f2  avg 22
A   B   f2  sd  10
B   B   f2  sd  11
C   B   f2  sd  8
D   B   f2  sd  9

请帮忙!

3 个答案:

答案 0 :(得分:2)

dplyrtidyr

library(dplyr)
library(tidyr)

X <- gather(dw, var, res, -sbj) %>%
    separate(var, into = c("AB", "f", "var"))

结果:

> head(X)
  sbj AB  f var res
1   A  A f1 avg  10
2   B  A f1 avg  12
3   C  A f1 avg  20
4   D  A f1 avg  22
5   A  A f1  sd   6
6   B  A f1  sd   5

答案 1 :(得分:1)

使用reshape2 ...

library(reshape2)
dw2 <- melt(dw, id.vars="sbj", value.name="res") #melt to long format

#create new variables by splitting column at dots
dw2[, c("AB", "f", "var")] <- t(as.data.frame((strsplit(as.character(dw2$variable),"\\."))))

#reorder variables
dw2 <- dw2[,c("sbj", "AB", "f", "var", "res")]

dw2
   sbj AB  f var   res
1    A  A f1 avg    10
2    B  A f1 avg    12
3    C  A f1 avg    20
4    D  A f1 avg    22
5    A  A f1  sd     6
6    B  A f1  sd     5
7    C  A f1  sd     7
8    D  A f1  sd     8
9    A  A f2 avg    50
10   B  A f2 avg    70
11   C  A f2 avg    20
12   D  A f2 avg    22
13   A  A f2  sd    10
14   B  A f2  sd    11
15   C  A f2  sd     8
16   D  A f2  sd     9
17   A  B f1 avg    10
18   B  B f1 avg    12
19   C  B f1 avg    20
20   D  B f1 avg    22
21   A  B f1  sd     6
22   B  B f1  sd     5
23   C  B f1  sd     7
24   D  B f1  sd     8
25   A  B f2 avg    50
26   B  B f2 avg    70
27   C  B f2 avg    20
28   D  B f2 avg    22
29   A  B f2  sd    10
30   B  B f2  sd    11
31   C  B f2  sd     8
32   D  B f2  sd     9

答案 2 :(得分:0)

这是一个基础R方法,它使用stackcbind作为初始&#34;重塑长&#34;然后执行第二步,将dw的变量名分解为单独的列。

# get a 3 column df
dat <- cbind(dw[1], stack(dw[-1]))

# split the variable names, reorder columns, and provide desired names
dat <- setNames(cbind(dat[1],
                      do.call(rbind, strsplit(as.character(dat$ind), ".", fixed=TRUE)),
                      dat[2]),
                 c("sbj", "AB", "f", "var", "res"))