分组DataFrame全连接后填充缺失分组值,保留完整x序列
问题:扩展数据框补全分组内的完整序列
示例数据
ladder = data.frame(x = 1:10) df <- data.frame( id = rep('a', 5), x = 6:10 ) > df id x 1 a 6 2 a 7 3 a 8 4 a 9 5 a 10
需求:扩展df,使每个id分组都包含x的完整序列1到10。
尝试的代码及问题
> df |> group_by(id) |> full_join(ladder, by = 'x') # A tibble: 10 × 2 # Groups: id [2] id x <chr> <int> 1 a 6 2 a 7 3 a 8 4 a 9 5 a 10 6 NA 1 7 NA 2 8 NA 3 9 NA 4 10 NA 5
结果中缺失的id值为NA,希望替换为分组值a,得到如下期望输出:
df id x 1 a 1 2 a 2 3 a 3 4 a 4 5 a 5 6 a 6 7 a 7 8 a 8 9 a 9 10 a 10
解决方法
方法1:使用tidyr::complete(推荐)
tidyr包的complete函数专门用于补全分组内的缺失序列,会自动保留分组变量的值:
library(tidyr) df |> group_by(id) |> complete(x = 1:10)
输出结果:
# A tibble: 10 × 2 # Groups: id [1] id x <chr> <int> 1 a 1 2 a 2 3 a 3 4 a 4 5 a 5 6 a 6 7 a 7 8 a 8 9 a 9 10 a 10
方法2:手动生成全组合再左连接
如果不想依赖tidyr,可以先创建id和x的所有可能组合,再与原数据左连接:
# 生成id唯一值与x序列的全组合 full_seq <- expand.grid(id = unique(df$id), x = 1:10) # 因为原数据中仅x部分缺失,直接使用这个全组合即可,若原数据有其他字段再左连接 result <- full_seq
方法3:修正原连接逻辑
原full_join的问题是分组信息没有关联到新增的x值,先提取唯一分组再交叉连接ladder:
df |> distinct(id) |> cross_join(ladder) |> left_join(df, by = c("id", "x")) |> select(id, x)
内容的提问来源于stack exchange,提问作者Doug Fir
相关产品推荐
相关产品推荐

