再次对数据框中的列重新排序
Reordering columns in data frame once again
我想对我的数据框中的列重新排序,但到目前为止我发现的并不令人满意。
我的数据框看起来像:
cnt <-as.factor(c("Country 1", "Country 2", "Country 3", "Country 1", "Country 2", "Country 3" ))
bnk <-as.factor(c("bank 1", "bank 2", "bank 3", "bank 1", "bank 2", "bank 3" ))
mayData <-data.frame(age=c(10,12,13,10,11,15), Country=cnt, Bank=bnk, q10=c(1,1,1,2,2,2),q11=c(1,1,1,2,2,2), q1=c(1,1,1,2,2,2), q9=c(1,1,1,2,2,2), q6=c(1,1,1,2,2,2), year=c(1950,1960,1970,1980,1990,2000) )
age Country Bank q10 q11 q1 q9 q6 year
1 10 Country 1 bank 1 1 1 1 1 1 1950
2 12 Country 2 bank 2 1 1 1 1 1 1960
3 13 Country 3 bank 3 1 1 1 1 1 1970
4 10 Country 1 bank 1 2 2 2 2 2 1980
5 11 Country 2 bank 2 2 2 2 2 2 1990
6 15 Country 3 bank 3 2 2 2 2 2 2000
但我想重新排列列,使其看起来像这样:
Country Bank year age q1 q6 q9 q10 q11
1 Country 1 bank 1 1950 10 1 1 1 1 1
2 Country 2 bank 2 1960 12 1 1 1 1 1
3 Country 3 bank 3 1970 13 1 1 1 1 1
4 Country 1 bank 1 1980 10 2 2 2 2 2
5 Country 2 bank 2 1990 11 2 2 2 2 2
6 Country 3 bank 3 2000 15 2 2 2 2 2
我的真实数据框有很多列,因此使用索引或每列的名称重新排列列顺序 "manually" 并不是最佳选择。
另请注意,对于以 q
s 开头的列名,我希望它们按升序排列,即从 q1
到 q11
。问题是 R 无法理解 q6
- 代表 "question 6" - 应该在 q10
之前。要了解此缺陷,请查看以下示例:
mayData<-mayData[,order(colnames(mayData),decreasing=F)]
age Bank Country q1 q10 q11 q6 q9 year
1 10 bank 1 Country 1 1 1 1 1 1 1950
2 12 bank 2 Country 2 1 1 1 1 1 1960
3 13 bank 3 Country 3 1 1 1 1 1 1970
4 10 bank 1 Country 1 2 2 2 2 2 1980
5 11 bank 2 Country 2 2 2 2 2 2 1990
6 15 bank 3 Country 3 2 2 2 2 2 2000
所以,基本上我想要重新排序我的列的方式是首先根据我的偏好以某种灵活的方式对一些列进行排序,然后使用递减的排序标准。但是,"logical" 一个,R 可以理解以正确排序 q
的一个。
您可以用单个数字重命名列名称以添加前导零:
cn <- names(mayData)
q_digit <- cn[grep("^q[0-9]$", cn)]
names(mayData)[names(mayData) %in% q_digit] <- gsub("q", "q0", q_digit)
mayData[,order(colnames(mayData),decreasing=F)]
mayData
age Bank Country q01 q06 q09 q10 q11 year
1 10 bank 1 Country 1 1 1 1 1 1 1950
2 12 bank 2 Country 2 1 1 1 1 1 1960
3 13 bank 3 Country 3 1 1 1 1 1 1970
4 10 bank 1 Country 1 2 2 2 2 2 1980
5 11 bank 2 Country 2 2 2 2 2 2 1990
6 15 bank 3 Country 3 2 2 2 2 2 2000
这假设您的问题少于 100 个,如果您有更多问题,您可以调整它以在两位数的列名称中添加另一个零。
我们可以使用 gtools
中的 mixedsort
来排列 'q' 列。
library(gtools)
i1 <- grep("q\d+", names(mayData))
nm1 <- mixedsort(names(mayData)[i1])
mayData[c(setdiff(names(mayData), nm1), nm1)]
# age Country Bank year q1 q6 q9 q10 q11
#1 10 Country 1 bank 1 1950 1 1 1 1 1
#2 12 Country 2 bank 2 1960 1 1 1 1 1
#3 13 Country 3 bank 3 1970 1 1 1 1 1
#4 10 Country 1 bank 1 1980 2 2 2 2 2
#5 11 Country 2 bank 2 1990 2 2 2 2 2
#6 15 Country 3 bank 3 2000 2 2 2 2 2
注意:仅使用 base R
函数和单个包。
或者如@Cath 提到的那样,用 gsub
删除子字符串也可以用来排序
sort(as.numeric(sub("^q", "", names(mayData)[i1])))
利用 dplyr
的 select
和 num_range
以及 tidyr::extract_numeric
:
library(dplyr)
library(tidyr)
mayData %>% select(Country, Bank, year, age,
num_range('q', sort(extract_numeric(names(mayData)))))
# Country Bank year age q1 q6 q9 q10 q11
# 1 Country 1 bank 1 1950 10 1 1 1 1 1
# 2 Country 2 bank 2 1960 12 1 1 1 1 1
# 3 Country 3 bank 3 1970 13 1 1 1 1 1
# 4 Country 1 bank 1 1980 10 2 2 2 2 2
# 5 Country 2 bank 2 1990 11 2 2 2 2 2
# 6 Country 3 bank 3 2000 15 2 2 2 2 2
我想对我的数据框中的列重新排序,但到目前为止我发现的并不令人满意。
我的数据框看起来像:
cnt <-as.factor(c("Country 1", "Country 2", "Country 3", "Country 1", "Country 2", "Country 3" ))
bnk <-as.factor(c("bank 1", "bank 2", "bank 3", "bank 1", "bank 2", "bank 3" ))
mayData <-data.frame(age=c(10,12,13,10,11,15), Country=cnt, Bank=bnk, q10=c(1,1,1,2,2,2),q11=c(1,1,1,2,2,2), q1=c(1,1,1,2,2,2), q9=c(1,1,1,2,2,2), q6=c(1,1,1,2,2,2), year=c(1950,1960,1970,1980,1990,2000) )
age Country Bank q10 q11 q1 q9 q6 year
1 10 Country 1 bank 1 1 1 1 1 1 1950
2 12 Country 2 bank 2 1 1 1 1 1 1960
3 13 Country 3 bank 3 1 1 1 1 1 1970
4 10 Country 1 bank 1 2 2 2 2 2 1980
5 11 Country 2 bank 2 2 2 2 2 2 1990
6 15 Country 3 bank 3 2 2 2 2 2 2000
但我想重新排列列,使其看起来像这样:
Country Bank year age q1 q6 q9 q10 q11
1 Country 1 bank 1 1950 10 1 1 1 1 1
2 Country 2 bank 2 1960 12 1 1 1 1 1
3 Country 3 bank 3 1970 13 1 1 1 1 1
4 Country 1 bank 1 1980 10 2 2 2 2 2
5 Country 2 bank 2 1990 11 2 2 2 2 2
6 Country 3 bank 3 2000 15 2 2 2 2 2
我的真实数据框有很多列,因此使用索引或每列的名称重新排列列顺序 "manually" 并不是最佳选择。
另请注意,对于以 q
s 开头的列名,我希望它们按升序排列,即从 q1
到 q11
。问题是 R 无法理解 q6
- 代表 "question 6" - 应该在 q10
之前。要了解此缺陷,请查看以下示例:
mayData<-mayData[,order(colnames(mayData),decreasing=F)]
age Bank Country q1 q10 q11 q6 q9 year
1 10 bank 1 Country 1 1 1 1 1 1 1950
2 12 bank 2 Country 2 1 1 1 1 1 1960
3 13 bank 3 Country 3 1 1 1 1 1 1970
4 10 bank 1 Country 1 2 2 2 2 2 1980
5 11 bank 2 Country 2 2 2 2 2 2 1990
6 15 bank 3 Country 3 2 2 2 2 2 2000
所以,基本上我想要重新排序我的列的方式是首先根据我的偏好以某种灵活的方式对一些列进行排序,然后使用递减的排序标准。但是,"logical" 一个,R 可以理解以正确排序 q
的一个。
您可以用单个数字重命名列名称以添加前导零:
cn <- names(mayData)
q_digit <- cn[grep("^q[0-9]$", cn)]
names(mayData)[names(mayData) %in% q_digit] <- gsub("q", "q0", q_digit)
mayData[,order(colnames(mayData),decreasing=F)]
mayData
age Bank Country q01 q06 q09 q10 q11 year
1 10 bank 1 Country 1 1 1 1 1 1 1950
2 12 bank 2 Country 2 1 1 1 1 1 1960
3 13 bank 3 Country 3 1 1 1 1 1 1970
4 10 bank 1 Country 1 2 2 2 2 2 1980
5 11 bank 2 Country 2 2 2 2 2 2 1990
6 15 bank 3 Country 3 2 2 2 2 2 2000
这假设您的问题少于 100 个,如果您有更多问题,您可以调整它以在两位数的列名称中添加另一个零。
我们可以使用 gtools
中的 mixedsort
来排列 'q' 列。
library(gtools)
i1 <- grep("q\d+", names(mayData))
nm1 <- mixedsort(names(mayData)[i1])
mayData[c(setdiff(names(mayData), nm1), nm1)]
# age Country Bank year q1 q6 q9 q10 q11
#1 10 Country 1 bank 1 1950 1 1 1 1 1
#2 12 Country 2 bank 2 1960 1 1 1 1 1
#3 13 Country 3 bank 3 1970 1 1 1 1 1
#4 10 Country 1 bank 1 1980 2 2 2 2 2
#5 11 Country 2 bank 2 1990 2 2 2 2 2
#6 15 Country 3 bank 3 2000 2 2 2 2 2
注意:仅使用 base R
函数和单个包。
或者如@Cath 提到的那样,用 gsub
删除子字符串也可以用来排序
sort(as.numeric(sub("^q", "", names(mayData)[i1])))
利用 dplyr
的 select
和 num_range
以及 tidyr::extract_numeric
:
library(dplyr)
library(tidyr)
mayData %>% select(Country, Bank, year, age,
num_range('q', sort(extract_numeric(names(mayData)))))
# Country Bank year age q1 q6 q9 q10 q11
# 1 Country 1 bank 1 1950 10 1 1 1 1 1
# 2 Country 2 bank 2 1960 12 1 1 1 1 1
# 3 Country 3 bank 3 1970 13 1 1 1 1 1
# 4 Country 1 bank 1 1980 10 2 2 2 2 2
# 5 Country 2 bank 2 1990 11 2 2 2 2 2
# 6 Country 3 bank 3 2000 15 2 2 2 2 2