如何使用首字母按列的排列顺序命名数据框

How to name dataframes by permutation order of columns using first letter

从单个 data.frame,我生成了与主 data.frame 中的列排列一样多的 data.frame。从这里开始,我希望 1) 每个排列 data.frame 通过保留每个列名称的第一个字母以排列顺序命名,2) cbind 每个 data.frames 与另一个:

data1 <- data.frame("Alpha"=c(1,2), "Beta"=c(2,2), "Gamma"=c(4,8))
data2 <- data.frame("Delta"=c(22,3))

library(combinat)
idx <- permn(ncol(data1))
res <- lapply(idx, function(x) data1[x])
res
[[1]]
  Alpha Beta Gamma
1     1    2     4
2     2    2     8

[[2]]
  Alpha Gamma Beta
1     1     4    2
2     2     8    2

[[3]]
  Gamma Alpha Beta
1     4     1    2
2     8     2    2

...

[[6]]
  Beta Alpha Gamma
1    2     1     4
2    2     2     8

首先,我希望每个前面的 data.frame 都按照排列顺序命名,保留每个列名称的第一个字母,这样它将显示以下 data.frames:

dataABG
  Alpha Beta Gamma
1     1    2     4
2     2    2     8

dataAGB
  Alpha Gamma Beta
1     1     4    2
2     2     8    2

dataGAB
  Gamma Alpha Beta
1     4     1    2
2     8     2    2

...

然后,我想 cbind 每个以前的数据帧 data2,保持以前的数据帧名称。

您可以使用 lapply 结合对单个数据框列名称的子字符串操作来创建名称。当然,这假设您要将所有列的每个首字母添加到名称中:

names(res) <- unlist(lapply(res,function(x) sprintf('data%s',paste0(substr(colnames(x),1,1),collapse = ''))))

res

# $dataABG
# Alpha Beta Gamma
# 1     1    2     4
# 2     2    2     8
# 
# $dataAGB
# Alpha Gamma Beta
# 1     1     4    2
# 2     2     8    2
# 
# $dataGAB
# Gamma Alpha Beta
# 1     4     1    2
# 2     8     2    2

现在要追加 data2 中的列,您可以再次使用 lapply:

lapply(res,function(x) cbind(x,data2))

# $dataABG
# Alpha Beta Gamma Delta
# 1     1    2     4    22
# 2     2    2     8     3
# 
# $dataAGB
# Alpha Gamma Beta Delta
# 1     1     4    2    22
# 2     2     8    2     3
# 
# $dataGAB
# Gamma Alpha Beta Delta
# 1     4     1    2    22
# 2     8     2    2     3

编辑:

为了尽量减少 lapply 的使用,您可以在 select 排列时已经 cbind data2 列,随后将其从名称创建中排除:

library(combinat)
idx <- permn(ncol(data1))
res <- lapply(idx, function(x) cbind(data1[x],data2))

names(res) <- unlist(lapply(res,function(x) sprintf('data%s',paste0(str_sub(colnames(x)[-length(colnames(x))],1,1),collapse = ''))))

这将为您节省整个 lapply 个电话。