R语言:如何按国家分组排序Sex列并将IND置于末尾?
分组内排序+指定国家位置的解决方法
需求说明
要实现两个排序规则:
- 每个国家分组内,Sex列按Male在前,Female在后排序;
- IND国家整体排在所有国家的最底部。
当前使用的order()写法会把所有Male/Female集中在一起,无法满足分组内排序的需求。
示例数据集
Country<- c("France","France", "Germnay", "Germnay", "UK", "UK", "IND", "IND") Sex <-c("Female", "Male", "Female", "Male", "Female", "Male", "Female", "Male") A<- c(10, 20, 30 ,40 ,50 ,60 ,70 ,80) B <- c(20, 30, 40, 50, 56, 84, 75, 85) dt <- data.frame(Country, Sex, A, B)
错误代码
dt <-dt[with(dt, order(dt$sex, decreasing = TRUE)),]
期望输出
Country<- c("France","France", "Germnay", "Germnay", "UK", "UK", "IND", "IND") Sex <-c("Male", "Female", "Male", "Female", "Male", "Female", "Male", "Female") A<- c(10, 20, 30 ,40 ,50 ,60 ,70 ,80) B <- c(20, 30, 40, 50, 56, 84, 75, 85) output <- data.frame(Country, Sex, A, B)
正确实现代码
方法一:简洁写法(无需临时列)
# 按「是否为IND」→「国家名称」→「性别优先级」排序 dt_sorted <- dt[order(dt$Country == "IND", dt$Country, -xtfrm(dt$Sex)), ]
方法二:分步理解写法(带临时列)
# 给国家设置排序标记:非IND为1,IND为2,确保IND排最后 dt$country_rank <- ifelse(dt$Country == "IND", 2, 1) # 按标记升序、国家名称升序、性别降序排序 dt_sorted <- dt[order(dt$country_rank, dt$Country, -xtfrm(dt$Sex)), ] # 移除临时标记列 dt_sorted <- dt_sorted[, !names(dt_sorted) %in% "country_rank"]
代码解释
dt$Country == "IND":生成逻辑向量,FALSE(非IND)对应数值0,TRUE(IND)对应数值1,升序排序后非IND国家会排在IND前面;dt$Country:保证非IND国家按原有字母顺序排列;-xtfrm(dt$Sex):xtfrm()将字符型的Sex转为可排序的数值,"Male"的数值大于"Female",加负号后降序排列,实现Male在前、Female在后的分组内排序。
运行上述代码后,得到的结果与期望输出完全一致。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

