在R中按指定规则实现多列交替排列行数据
数据框排序问题解决方案
问题描述
现有如下结构的data.frame:
structure(list(user = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"), group = c("G2", "G2", "G2", "G2", "G1", "G1", "G2", "G2", "G2", "G1", "G2", "G1", "G1", "G2", "G1", "G2"), gender = c("M", "H", "H", "M", "M", "M", "M", "M", "M", "M", "M", "M", "H", "H", "M", "H"), level = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L)), row.names = c(NA, -16L), class = c("tbl_df", "tbl", "data.frame"))
需求
- 先按分组排序,所有
G1组的观测值排在G2组前面; - 在各组内,按
M、H、M、H……的交替顺序排列gender,同时保持level按1、2、3、4的顺序排列。
之前的尝试
尝试了以下两种代码,但均未得到预期结果:
db%>% arrange(group, gender, level)
db %>% arrange(factor(group, levels = c("G1", "G2")), factor(gender, levels= c("M", "H")), factor(level, levels= c(1, 2, 3, 4)))
解决方案
之前的代码会把同一组内所有M排完再排H,无法实现交替效果。要达成需求,需要给每个组内的gender分组生成序号,再按序号与gender的组合排序:
library(dplyr) db %>% # 确保G1组排在G2组之前 arrange(factor(group, levels = c("G1", "G2"))) %>% # 按组和性别分组,给每组内的观测生成连续序号 group_by(group, gender) %>% mutate(rn = row_number()) %>% ungroup() %>% # 按组、序号、性别排序,指定M优先实现交替效果 arrange(group, rn, factor(gender, levels = c("M", "H")))
原理说明
- 通过
factor(group, levels = c("G1", "G2"))强制指定分组的排序优先级; - 用
group_by(group, gender)+row_number(),给每个组内的M和H分别生成独立的连续序号(比如G1组的M会得到rn=1、2、3、4,H得到rn=1); - 最后按
group、rn、gender排序,同一序号下先排M再排H,自然形成交替效果,同时level会跟着序号对应保持1-4的顺序。
内容的提问来源于stack exchange,提问作者Alejandro Carrera
相关产品推荐
相关产品推荐

