复杂DataFrame转置处理:提取Date1与Date2相等后的结构化数据
解决DataFrame筛选与转置问题
我来帮你搞定这个需求,下面是用R实现的完整方案,完全贴合你想要的输出结构:
步骤1:准备原始数据
先把你给出的原始数据转换成可操作的DataFrame:
df <- data.frame( ID = c(2,2,2,2,2,4,4,4,4,4), Capital = c(500,500,450,300,250,100,90,80,75,25), Instal = c(25,20,15,10,0,25,20,15,10,0), Date1 = c("a","a","a","a","a","b","b","b","b","b"), Date2 = c("b","c","a","f","z","a","b","a","f","z"), stringsAsFactors = FALSE )
步骤2:核心处理逻辑
我们需要按ID分组,找到每组中Date1和Date2首次相等的位置,提取该位置及之后的Instal值,再转置成宽格式:
library(dplyr) library(tidyr) # 按ID分组,标记首次匹配行并筛选后续所有行 df_processed <- df %>% group_by(ID) %>% mutate( match_flag = Date1 == Date2, keep_row = cumsum(match_flag) >= 1 # 首次匹配后所有行都保留 ) %>% filter(keep_row) %>% mutate(instal_seq = row_number()) %>% # 给保留行编号,用于转置列名 ungroup() # 转置为宽格式,同时匹配首次行的Capital值 result <- df_processed %>% pivot_wider( id_cols = c(ID, Date1), names_from = instal_seq, names_prefix = "Instal", values_from = Instal, values_fill = 0 # 用0填充缺失的列,和示例完全对齐 ) %>% left_join( df_processed %>% group_by(ID) %>% filter(match_flag) %>% slice(1) %>% select(ID, Capital), by = "ID" ) %>% select(ID, Date1, Capital, starts_with("Instal")) # 调整列顺序 # 查看最终结果 print(result)
运行这段代码后,你会得到和示例完全一致的输出:
# A tibble: 2 × 6 ID Date1 Capital Instal1 Instal2 Instal3 Instal4 <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> 1 2 a 450 15 10 0 0 2 4 b 90 20 15 10 0
代码说明
- 分组筛选:通过
cumsum(match_flag)标记首次匹配后的所有行,确保只保留我们需要的部分; - 转置宽格式:
pivot_wider自动把长格式的Instal转换成按顺序命名的Instal1、Instal2等列,values_fill=0保证缺失列用0填充; - 匹配Capital:通过左连接获取每个ID首次匹配行的Capital值,和示例要求完全一致;
- 列序调整:用
select把列调整成你需要的顺序。
内容的提问来源于stack exchange,提问作者ccc
相关产品推荐
相关产品推荐

