将R数据帧从长格式转换为宽格式,但具有不相等的组大小,以便与qcc一起使用

时间:2015-07-29 12:09:19

标签: r reshape qcc

我想将数据帧从长格式转换为宽格式,但具有不相等的组大小。

最终的使用将在' qcc'中,这需要一个数据框或矩阵,每行由一个组组成,使用NA组,其中样本数较少。

以下代码将创建一个示例数据集,并显示手动转换为所需格式。

# This is an example of the initial data that I have
# * 10 sample measurements, over 3 groups with 3, 2, and 5 elements respectively
x <- rnorm(10)
x_df <- data.frame( time = c( rep('2001 Q1',3), rep('2001 Q2',2), rep('2001 Q3',5) ), measure = x )
x_df

# This is a manual conversion into the desired format
x_pad <- c( x[1:3], NA, NA, x[4:5], NA, NA, NA, x[6:10] )
x_matrix <- matrix( x_pad, nrow = 3, ncol = 5, byrow = TRUE, dimnames = list(c('2001 Q1','2001 Q2','2001 Q3')) )
x_matrix # desired format

# An example of how it will be used
library(qcc)
plot(qcc(x_matrix, type = 'xbar', plot = FALSE))

所以,我想转换一下:

      time     measure
1  2001 Q1  0.14680685
2  2001 Q1  0.53593193
3  2001 Q1  0.56097974
4  2001 Q2 -1.48102689
5  2001 Q2  0.18150972
6  2001 Q3  1.72018147
7  2001 Q3 -0.08480855
8  2001 Q3 -2.23208877
9  2001 Q3 -1.15269107
10 2001 Q3  0.57975023

......对此...

              [,1]        [,2]       [,3]      [,4]      [,5]
2001 Q1  0.1468068  0.53593193  0.5609797        NA        NA
2001 Q2 -1.4810269  0.18150972         NA        NA        NA
2001 Q3  1.7201815 -0.08480855 -2.2320888 -1.152691 0.5797502

可能有一种简单的方法(也许是我不熟悉的重塑或重塑的一些用法?),但到目前为止,一堆搜索并没有帮助我。

感谢您的帮助!

==========

通过以下解决方案之一,以下内容将生成最终的qcc xbar图,包括组标签:

library(splitstackshape)
out_df <- dcast( getanID( x_df, 'time' ), time~.id, value.var='measure' )
qcc( out_df[,-1], type = 'xbar', labels = out_df[,1] )

3 个答案:

答案 0 :(得分:7)

您需要一个提供“及时”ID的中间变量。您可以创建它并像这样重塑

library(tidyr)
library(dplyr)

group_by(X, time) %>%
  mutate(seq = 1:n()) %>%
  ungroup() %>%
  spread(seq, measure)

答案 1 :(得分:6)

您可以使用getanID中的splitstackshape创建序列列('.id'),并使用dcast中的data.table将长格式转换为宽格式。 splitstackshape的输出是data.table。加载splitstackshape时,还会加载data.table。因此,如果您已经拥有了data.table的devel版本,则也可以使用dcast中的data.table

library(splitstackshape)
dcast(getanID(df1, 'time'), time~.id, value.var='measure')
#     time          1           2          3         4         5
#1: 2001 Q1  0.1468068  0.53593193  0.5609797        NA        NA
#2: 2001 Q2 -1.4810269  0.18150972         NA        NA        NA
#3: 2001 Q3  1.7201815 -0.08480855 -2.2320888 -1.152691 0.5797502

更新

正如@snoram在评论中提到的那样,来自rowid的函数data.table可以更轻松地仅使用data.table

library(data.table)
dcast(setDT(df1), time ~ rowid(time), value.var = "measure")

答案 2 :(得分:5)

另一种splitstackshape方法

cSplit(setDT(df)[, toString(measure), by='time'], 'V1', ',')

#      time       V1_1        V1_2       V1_3      V1_4      V1_5
#1: 2001 Q1  0.1468068  0.53593193  0.5609797        NA        NA
#2: 2001 Q2 -1.4810269  0.18150972         NA        NA        NA
#3: 2001 Q3  1.7201815 -0.08480855 -2.2320888 -1.152691 0.5797502

使用devel data.table版本的tstrsplit类似方法将“&#39;测量”粘贴在一起通过分组列&#39; time&#39;将使用toString(measure)分割&#39; V1&#39;从 setDT(df)[, toString(measure), by ='time'][, c(list(time), tstrsplit(V1, ', '))] 生成的列。

type.convert=TRUE

另外,我们可以在tstrsplit中添加class来转换拆分列的FALSE。默认情况下为CardView