如何用dplyr基于嵌套数据生成Level2列?已实现Level1
用dplyr生成Level2列的实现方案
示例数据
先构造符合结构的测试数据(包含已生成的Level1列):
library(dplyr) library(tidyr) df <- tibble( Type = c("CAT", "SUB", "SUB", "CAT", "SUB", "SUB", "SUB", "CAT", "SUB"), Name = c("消化系统疾病", "胃炎", "胃溃疡", "呼吸系统疾病", "感冒", "肺炎", "支气管炎", "心血管疾病", "高血压"), Number = c(2, 0, 0, 3, 0, 0, 0, 1, 0), Level1 = c("消化系统疾病", "消化系统疾病", "消化系统疾病", "呼吸系统疾病", "呼吸系统疾病", "呼吸系统疾病", "呼吸系统疾病", "心血管疾病", "心血管疾病") )
实现代码
通过临时标记填充范围的方式实现Level2列:
df <- df %>% # 标记需要填充的行的行号和填充行数 mutate( fill_id = ifelse(Number > 0, row_number(), NA), fill_n = ifelse(Number > 0, Number, NA) ) %>% # 向下填充标记值,让所有待填充的子行继承父行的填充规则 fill(fill_id, fill_n, .direction = "down") %>% # 根据行号判断是否在填充范围内,生成Level2 mutate( Level2 = ifelse(row_number() <= fill_id + fill_n, Name[fill_id], Name) ) %>% # 清理临时列 select(-fill_id, -fill_n)
代码逻辑说明
- 标记填充源:为所有
Number>0的行记录当前行号(fill_id)和需要填充的行数(fill_n),其他行设为NA。 - 继承填充规则:向下填充
fill_id和fill_n,让每个需要被填充的子类别行都能获取到上方父行的填充参数。 - 生成Level2:判断当前行号是否在父行的填充范围内(当前行号 ≤ 父行行号 + 填充行数),若是则使用父行的
Name,否则使用自身Name。 - 清理临时数据:移除用于计算的临时列。
嵌套子类别测试
如果存在嵌套的子类别(即子类别行的Number>0),该方案同样适用:
# 嵌套结构测试数据 df_nested <- tibble( Type = c("CAT", "SUB", "SUB", "SUB", "SUB"), Name = c("消化系统疾病", "胃炎", "急性胃炎", "慢性胃炎", "胃溃疡"), Number = c(3, 2, 0, 0, 0), Level1 = c("消化系统疾病", "消化系统疾病", "消化系统疾病", "消化系统疾病", "消化系统疾病") ) # 应用相同代码 df_nested <- df_nested %>% mutate( fill_id = ifelse(Number > 0, row_number(), NA), fill_n = ifelse(Number > 0, Number, NA) ) %>% fill(fill_id, fill_n, .direction = "down") %>% mutate( Level2 = ifelse(row_number() <= fill_id + fill_n, Name[fill_id], Name) ) %>% select(-fill_id, -fill_n) print(df_nested)
输出结果会自动处理嵌套填充:第2行(Name=胃炎,Number=2)的Name会向下填充2行,第5行不在填充范围内,使用自身Name=胃溃疡。
内容的提问来源于stack exchange,提问作者Kartik
相关产品推荐
相关产品推荐

