如何基于DataFrame中另一列的分组排列创建新列?
看了你的DataFrame结构,每个grouping组内的var和order有对应的排列关系(比如site1_1里是P→G→B对应0→1→2,site2_1里是P→B→G对应0→1→2)。下面给你几个常用的实现方式,用dplyr包来处理,代码简洁直观:
首先先确认你的完整数据:
df <- data.frame( grouping = c(rep("site1_1",9), rep("site2_1",9)), var = c(rep("P", 3), rep("G", 3), rep("B",3), rep("P", 3), rep("B", 3), rep("G",3)), order= c(rep(0, 3), rep(1, 3), rep(2,3), rep(0, 3), rep(1, 3), rep(2,3)) )
1. 基于order列生成自定义标签列
如果想把order的数值转换成更易读的分类标签(比如"第一阶段"、"第二阶段"),直接用mutate+case_when即可:
library(dplyr) df <- df %>% mutate( stage_label = case_when( order == 0 ~ "First Stage", order == 1 ~ "Second Stage", order == 2 ~ "Third Stage", TRUE ~ NA_character_ # 处理意外值 ) )
这个方法不需要分组,因为order列的数值已经对应了全局的阶段划分。
2. 按grouping分组,生成组内专属的顺序列
如果你想让每个分组内,var的出现顺序(对应order的排序)生成一个组内的序号(比如每个组的第一个出现的var标记为1,第二个为2,以此类推),可以结合group_by和dense_rank:
df <- df %>% group_by(grouping) %>% mutate( group_inner_order = dense_rank(order) # 自动将0→1, 1→2, 2→3 # 如果你不想依赖order列,也可以用var的首次出现顺序: # group_inner_order = dense_rank(match(var, unique(var))) ) %>% ungroup()
运行后,site1_1里的G对应的group_inner_order是2,site2_1里的B对应的也是2,完美实现了分组内的顺序标记。
3. 分组后将var映射为统一类别
如果想让每个分组内的第N个var都对应同一个类别标签(比如不管是G还是B,只要是组内第二个出现的都叫"中间组"),可以这样写:
df <- df %>% group_by(grouping) %>% mutate( unified_group = case_when( order == 0 ~ "Start", order == 1 ~ "Middle", order == 2 ~ "End", TRUE ~ NA_character_ ) ) %>% ungroup()
结果示例
以方案2为例,处理后的前15行数据会是这样:
grouping var order group_inner_order
1 site1_1 P 0 1
2 site1_1 P 0 1
3 site1_1 P 0 1
4 site1_1 G 1 2
5 site1_1 G 1 2
6 site1_1 G 1 2
7 site1_1 B 2 3
8 site1_1 B 2 3
9 site1_1 B 2 3
10 site2_1 P 0 1
11 site2_1 P 0 1
12 site2_1 P 0 1
13 site2_1 B 1 2
14 site2_1 B 1 2
15 site2_1 B 1 2
这样就完全根据分组内的排列生成了你需要的新列。
内容的提问来源于stack exchange,提问作者cebola

