将 R 数据帧从长格式转换为宽格式,但组大小不相等,用于 qcc
Convert R dataframe from long to wide format, but with unequal group sizes, for use with 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
可能有一个简单的方法(也许是我不熟悉的 reshape 或 reshape2 casting 的一些用法?),但到目前为止,一堆搜索对我没有帮助。
感谢您的帮助!
==========
从下面的解决方案之一,以下将生成最终的 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] )
您需要一个提供 "within-time" ID 的中间变量。您可以像这样创建和重塑它
library(tidyr)
library(dplyr)
group_by(X, time) %>%
mutate(seq = 1:n()) %>%
ungroup() %>%
spread(seq, measure)
您可以使用 splitstackshape
中的 getanID
创建序列列 ('.id') 并使用 data.table
中的 dcast
将长格式转换为宽格式. splitstackshape
的输出是 data.table。当我们加载splitstackshape
时,data.table也会被加载。因此,如果您已经拥有 data.table 的开发版本,那么也可以使用 data.table
中的 dcast
。
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 在评论中提到的,data.table
中的函数 rowid
可以更轻松地单独使用 data.table
library(data.table)
dcast(setDT(df1), time ~ rowid(time), value.var = "measure")
另一种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
或者使用 data.table
的 devel
版本,通过分组列 'time' 将 'measure' 粘贴在一起后,类似的方法将使用 tstrsplit
来拆分从 toString(measure)
.
生成的 'V1' 列
setDT(df)[, toString(measure), by ='time'][, c(list(time), tstrsplit(V1, ', '))]
另外,我们可以在tstrsplit
中加入type.convert=TRUE
来转换拆分列的class
。默认为 FALSE
.
我想将数据帧从长格式转换为宽格式,但组大小不相等。
最终会在'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
可能有一个简单的方法(也许是我不熟悉的 reshape 或 reshape2 casting 的一些用法?),但到目前为止,一堆搜索对我没有帮助。
感谢您的帮助!
==========
从下面的解决方案之一,以下将生成最终的 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] )
您需要一个提供 "within-time" ID 的中间变量。您可以像这样创建和重塑它
library(tidyr)
library(dplyr)
group_by(X, time) %>%
mutate(seq = 1:n()) %>%
ungroup() %>%
spread(seq, measure)
您可以使用 splitstackshape
中的 getanID
创建序列列 ('.id') 并使用 data.table
中的 dcast
将长格式转换为宽格式. splitstackshape
的输出是 data.table。当我们加载splitstackshape
时,data.table也会被加载。因此,如果您已经拥有 data.table 的开发版本,那么也可以使用 data.table
中的 dcast
。
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 在评论中提到的,data.table
中的函数 rowid
可以更轻松地单独使用 data.table
library(data.table)
dcast(setDT(df1), time ~ rowid(time), value.var = "measure")
另一种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
或者使用 data.table
的 devel
版本,通过分组列 'time' 将 'measure' 粘贴在一起后,类似的方法将使用 tstrsplit
来拆分从 toString(measure)
.
setDT(df)[, toString(measure), by ='time'][, c(list(time), tstrsplit(V1, ', '))]
另外,我们可以在tstrsplit
中加入type.convert=TRUE
来转换拆分列的class
。默认为 FALSE
.