首先让我创建一些测试数据:
dat <- data.frame(Model_A=rnorm(10, 10), Model_B=rnorm(10, 12), Data_A=rnorm(10, 11),
Data_B=rnorm(10, 13))
# this produces the following
dat
Model_A Model_B Data_A Data_B
1 10.421684 13.201037 11.711313 13.18555
2 9.529258 11.086655 12.015787 14.13989
3 9.483633 10.697859 10.123176 15.50154
4 10.623490 11.171480 9.406222 12.56696
5 10.460739 10.925262 10.640612 11.98662
6 9.351494 10.276617 11.717629 13.00709
7 10.264206 11.587463 10.653878 13.33615
8 10.183569 13.187894 10.127552 13.87615
9 8.832003 9.739279 10.970686 13.26850
10 10.932207 11.974472 10.374939 12.11782
我希望能够做的是将所有列“堆叠”成两个名为“模型”和“数据”的列。列包含各个“模型”和“数据”列的唯一组合。我还想创建一个对数据进行分类的索引列。我想创建的数据集是:
Cat Model Data
Model_A_Data_A 10.421684 11.711313
Model_A_Data_A 9.529258 12.015787
Model_A_Data_A 9.483633 10.123176
Model_A_Data_A 10.62349 9.406222
Model_A_Data_A 10.460739 10.640612
Model_A_Data_A 9.351494 11.717629
Model_A_Data_A 10.264206 10.653878
Model_A_Data_A 10.183569 10.127552
Model_A_Data_A 8.832003 10.970686
Model_A_Data_A 10.932207 10.374939
Model_A_Data_B 10.421684 13.18555
Model_A_Data_B 9.529258 14.13989
Model_A_Data_B 9.483633 15.50154
Model_A_Data_B 10.62349 12.56696
Model_A_Data_B 10.460739 11.98662
Model_A_Data_B 9.351494 13.00709
Model_A_Data_B 10.264206 13.33615
Model_A_Data_B 10.183569 13.87615
Model_A_Data_B 8.832003 13.2685
Model_A_Data_B 10.932207 12.11782
Model_B_Data_A 13.201037 11.711313
Model_B_Data_A 11.086655 12.015787
Model_B_Data_A 10.697859 10.123176
Model_B_Data_A 11.17148 9.406222
Model_B_Data_A 10.925262 10.640612
Model_B_Data_A 10.276617 11.717629
Model_B_Data_A 11.587463 10.653878
Model_B_Data_A 13.187894 10.127552
Model_B_Data_A 9.739279 10.970686
Model_B_Data_A 11.974472 10.374939
Model_B_Data_B 13.201037 13.18555
Model_B_Data_B 11.086655 14.13989
Model_B_Data_B 10.697859 15.50154
Model_B_Data_B 11.17148 12.56696
Model_B_Data_B 10.925262 11.98662
Model_B_Data_B 10.276617 13.00709
Model_B_Data_B 11.587463 13.33615
Model_B_Data_B 13.187894 13.87615
Model_B_Data_B 9.739279 13.2685
Model_B_Data_B 11.974472 12.11782
我认为必须能够使用reshape包中的一些工具来完成,但我无法理解如何使用“Model”和“Data”列的所有独特组合来获取索引列。
值得注意的是,我的实际数据集中有9个“模型”columans和15个“数据”列。
谢谢。
答案 0 :(得分:1)
您可以尝试
combn(colnames...)
)split
“indx2”by“columns”创建列表(“lst”)根据“lst”名称对“dat”进行子集,并使用unnest
中的tidyr
来搜索列表元素。
library(tidyr)
indx <- combn(colnames(dat),2)
indx1 <- apply(indx, 2, function(x) length(unique(sub('_.*', '', x)))>1)
indx2 <- indx[,indx1]
lst <- split(indx2, col(indx2))
names(lst) <- apply(indx2, 2, paste, collapse='_')
res <- unnest(lapply(lst,function(x) {
x1 <- dat[x]
colnames(x1) <- c('Model', 'Data')
x1}), Cat)
head(res,2)
# Cat Model Data
#1 Model_A_Data_A 9.676133 9.491202
#2 Model_A_Data_A 11.599942 10.446249
或者您可以使用expand.grid
和rbindlist
data.table
indx <- expand.grid(split(colnames(dat),
sub("_.*", '', colnames(dat))))[2:1]
indx1 <- transform(indx, Cat=paste(Model, Data, sep="_"))
library(data.table)
res1 <- rbindlist(apply(indx1, 1, function(x) {
x1 <- unname(x)
data.frame(Cat=x1[3],dat[x1[1:2]])}))
答案 1 :(得分:1)
这也是一个可能的选择:
dat <- data.frame(Model_A=rnorm(10, 10), Model_B=rnorm(10, 12), Data_A=rnorm(10, 11),
Data_B=rnorm(10, 13))
model.names <- grep("Model",names(dat),value=TRUE)
data.names <- grep("Data",names(dat),value=TRUE)
new.dat <-
lapply(model.names,function(m) {
lapply(data.names,function(d) {
md <- cbind(dat[,m],dat[,d])
md.name <- rep(paste0(m,"_",d),nrow(md))
data.frame(md.name,md)
})
})
new.dat <- do.call(rbind,lapply(new.dat,function(l) do.call(rbind,l)))
names(new.dat) <- c("Cat","Model","Data")
首先,它提取模型和数据列的名称。 Aferwards,使用lapply两次,它为模型和数据的每个组合创建一个数据框,在第一列中放置适当的名称。最后一步是将所有这些数据帧放在一个双重嵌套列表中,放在一个数据框中。