dplyr add_row给分组数据误加整表而非单行的问题及解决需求
问题与解决方案
原始数据
数据结构如下:
> head(df) Sample Site Site.Type Substrate.Type Date Emerged 1 A 1 6/5 A Type1 TypeA 6/2/22 NA 2 A 1 6/5 A Type1 TypeA 6/3/22 NA 3 A 1 6/5 A Type1 TypeA 6/4/22 NA 4 A 1 6/5 A Type1 TypeA 6/5/22 0 5 A 1 6/5 A Type1 TypeA 6/6/22 0 6 A 1 6/5 A Type1 TypeA 6/7/22 0
> tail(df) Sample Site Site.Type Substrate.Type Date Emerged 27 C 3 6/12 B Type3 TypeR 6/12/22 NA 28 C 3 6/12 B Type3 TypeR 6/13/22 0 29 C 3 6/12 B Type3 TypeR 6/14/22 0 30 C 3 6/12 B Type3 TypeR 6/15/22 1 31 C 3 6/12 B Type3 TypeR 6/16/22 1 32 C 3 6/12 B Type3 TypeR 6/17/22 0
需求
为每个样本添加指定日期的行(如6/18/22,Emerged=0),或扩展为添加连续日期的多行。
原代码问题
你使用的代码会导致数据框长度翻倍,原因是.$Sample这类写法会提取分组内所有行的对应列值(比如每个样本有n行,就会传入n个重复的Sample值),add_row会据此添加n行而非1行。
解决方案
1. 为每个样本添加单行指定日期
使用group_modify结合first()提取分组内唯一的样本属性,确保只添加一行:
library(dplyr) library(tibble) df_updated <- df %>% group_by(Sample) %>% group_modify(~ add_row(.x, Sample = first(.x$Sample), Site = first(.x$Site), Site.Type = first(.x$Site.Type), Substrate.Type = first(.x$Substrate.Type), Date = "6/18/22", Emerged = 0)) %>% ungroup()
2. 为每个样本添加连续日期的多行
如果需要添加一段连续日期的行,可以先定义目标日期序列,再生成对应行数的新数据并合并:
# 定义要添加的连续日期 target_dates <- c("6/18/22", "6/19/22", "6/20/22") df_multi_updated <- df %>% group_by(Sample) %>% group_modify(~ { # 生成要添加的多行数据 new_rows <- tibble( Sample = first(.x$Sample), Site = first(.x$Site), Site.Type = first(.x$Site.Type), Substrate.Type = first(.x$Substrate.Type), Date = target_dates, Emerged = 0 ) # 合并原数据与新行 bind_rows(.x, new_rows) }) %>% ungroup()
更灵活的日期生成(推荐)
先将Date列转换为日期类型,方便生成连续日期序列:
# 转换日期格式为Date类型 df <- df %>% mutate(Date = as.Date(Date, format = "%m/%d/%y")) # 生成2022-06-18至2022-06-20的连续日期 start_date <- as.Date("2022-06-18") end_date <- as.Date("2022-06-20") target_dates_seq <- seq(start_date, end_date, by = "day") df_multi_updated <- df %>% group_by(Sample) %>% group_modify(~ { new_rows <- tibble( Sample = first(.x$Sample), Site = first(.x$Site), Site.Type = first(.x$Site.Type), Substrate.Type = first(.x$Substrate.Type), Date = target_dates_seq, Emerged = 0 ) bind_rows(.x, new_rows) }) %>% ungroup() # 可选:转回原日期字符串格式 df_multi_updated <- df_multi_updated %>% mutate(Date = format(Date, "%m/%d/%y"))
内容的提问来源于stack exchange,提问作者CarBarb
相关产品推荐
相关产品推荐

