将所有列堆叠成两列,并在 R 中使用分类列
Stack all columns into two columns with categorical column in R
首先让我创建一些测试数据:
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
我想要做的是将所有列 'stack' 分成两个列,分别称为 "Model" 和 "Data"。这些列包含各个 "Model" 和 "Data" 列的每个唯一组合。我还想创建一个对数据进行分类的索引列。我要创建的数据集是:
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
我认为必须能够使用重塑包中的一些工具来完成,但我无法理解如何使用 "Model" 和 [ 的所有独特组合在其中获取索引列=23=] 列。
值得注意的是我的实际数据集有 9 "Model" 列和 15 "Data" 列。
谢谢。
你可以试试
- 正在创建 "column names" (
combn(colnames...)
) 的组合
- 从 "indx" 中删除属于同一类型的名称(即 Data_A、Data_B 或 Model_A、Model_B)
- 子集 "indx" 以创建 "indx2"
split
"indx2" 通过 "columns" 创建列表 ("lst")
- 更改 "lst" 的名称以标识组 ("Cat")
根据 "lst" 名称对 "dat" 进行子集化,并使用 tidyr
中的 unnest
来绑定列表元素。
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
和 data.table
中的 rbindlist
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]])}))
这也是一个可能的解决方案:
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 两次,它为模型和数据的每个组合创建一个数据框,将适当的名称放在第一列中。最后一步是将所有这些位于双层嵌套列表中的数据框放入单个数据框中。
首先让我创建一些测试数据:
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
我想要做的是将所有列 'stack' 分成两个列,分别称为 "Model" 和 "Data"。这些列包含各个 "Model" 和 "Data" 列的每个唯一组合。我还想创建一个对数据进行分类的索引列。我要创建的数据集是:
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
我认为必须能够使用重塑包中的一些工具来完成,但我无法理解如何使用 "Model" 和 [ 的所有独特组合在其中获取索引列=23=] 列。
值得注意的是我的实际数据集有 9 "Model" 列和 15 "Data" 列。
谢谢。
你可以试试
- 正在创建 "column names" (
combn(colnames...)
) 的组合
- 从 "indx" 中删除属于同一类型的名称(即 Data_A、Data_B 或 Model_A、Model_B)
- 子集 "indx" 以创建 "indx2"
split
"indx2" 通过 "columns" 创建列表 ("lst")- 更改 "lst" 的名称以标识组 ("Cat")
根据 "lst" 名称对 "dat" 进行子集化,并使用
tidyr
中的unnest
来绑定列表元素。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
和 data.table
rbindlist
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]])}))
这也是一个可能的解决方案:
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 两次,它为模型和数据的每个组合创建一个数据框,将适当的名称放在第一列中。最后一步是将所有这些位于双层嵌套列表中的数据框放入单个数据框中。