R语言:分组数据中按指定规则生成标记列的实现问题
按分组规则生成flag列的R实现
原始数据
首先定义数据框df:
df <- data.frame( group = c("a", "a", "a", "a", "b", "b", "c", "c", "c", "c", "d", "d", "d", "e", "e", "e", "e"), col1 = c(-36,10,-5,1, 0, 5,10, 5, 20, 2, -1, 1, 2, -10, -5, -1, 10 ) )
原始数据输出:
group col1 1 a -36 2 a 10 3 a -5 4 a 1 5 b 0 6 b 5 7 c 10 8 c 5 9 c 20 10 c 2 11 d -1 12 d 1 13 d 2 14 e -10 15 e -5 16 e -1 17 e 10
需求规则
- 若分组内
col1存在值1,则仅该条记录的flag设为"Y",同组其他记录设为空白; - 若分组内无值1但存在≤1的值,则将分组内
col1≤1的记录中最大值对应的那条flag设为"Y",同组其他记录(包括col1>1的)设为空白; - 其他情况所有记录的
flag设为空白。
问题分析
你尝试的代码缺少分组操作,dplyr中的any()、max()默认作用于整个数据集,而非每个分组,因此无法得到正确结果。此外规则2中需要取的是col1≤1子集的最大值,而非整个分组的最大值,这一点也需要修正。
修正后的代码
library(dplyr) df_result <- df %>% group_by(group) %>% mutate( # 计算分组内col1≤1的最大值,无符合条件值时返回NA max_le1 = max(col1[col1 <= 1], na.rm = TRUE), flag = case_when( # 规则1:分组内有1,仅col1=1的行设为Y any(col1 == 1) ~ ifelse(col1 == 1, "Y", ""), # 规则2:无1但存在≤1的值,且当前行col1等于该子集的最大值 !is.na(max_le1) & !any(col1 == 1) ~ ifelse(col1 == max_le1, "Y", ""), # 规则3:其他情况设为空白 TRUE ~ "" ) ) %>% # 移除临时计算的max_le1列 select(-max_le1) %>% ungroup()
输出结果
运行上述代码后得到的结果与期望一致:
group col1 flag 1 a -36 2 a 10 3 a -5 4 a 1 Y 5 b 0 Y 6 b 5 7 c 10 8 c 5 9 c 20 10 c 2 11 d -1 12 d 1 Y 13 d 2 14 e -10 15 e -5 16 e -1 Y 17 e 10
内容的提问来源于stack exchange,提问作者karuno
相关产品推荐
相关产品推荐

