在R中添加新行,用其他行的值替换DataFrame中的NA
问题描述
我有如下结构的DataFrame:
ID Col2 Col3 Col4 Col5 ID_1 JDH 43 FJS f8j ID_8 ABC 73 *NA* *NA* ID_7 AFE 03 *NA* k32 ID_8 *NA* *NA* FDS z7d
其中部分行存在重复ID(比如示例中的ID_8),后续列的非NA值互补无重叠。我希望将这些重复ID的行合并为一行无NA的新行,命名为ID_8_New,处理后的数据框如下:
ID Col2 Col3 Col4 Col5 ID_1 JDH 43 FJS f8j ID_8 ABC 73 *NA* *NA* ID_7 AFE 03 *NA* k32 ID_8 *NA* *NA* FDS z7d ID_8_New ABC 73 FDS z7d
实际数据中有大量这类重复ID的行,请问如何实现该需求?
附数据子集的dput结构:
structure(list(Company = c("CompanyA", "CompanyA"), Ticker = c("A", "A"), Ticker_Unq = c("A1", "A2"), Description = c(NA, "Text" ), Type = c("Token", NA)), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
可以用dplyr和tidyr包实现,核心逻辑是按重复分组列(示例为ID,实际数据为Company+Ticker)分组,提取每组非NA值合并成新行,再追加到原数据框。
示例数据处理代码
假设原数据框名为df:
library(dplyr) library(tidyr) # 构造示例数据 df <- tibble( ID = c("ID_1", "ID_8", "ID_7", "ID_8"), Col2 = c("JDH", "ABC", "AFE", NA), Col3 = c("43", "73", "03", NA), Col4 = c("FJS", NA, NA, "FDS"), Col5 = c("f8j", NA, "k32", "z7d") ) # 生成合并后的新行 merged_rows <- df %>% group_by(ID) %>% filter(n() > 1) %>% # 仅处理有重复行的组 summarise(across(everything(), ~ first(na.omit(.x))), .groups = "drop") %>% mutate(ID = paste0(ID, "_New")) # 重命名ID为原ID_New格式 # 合并新行到原数据 result_df <- bind_rows(df, merged_rows) print(result_df)
实际数据处理代码
针对你提供的实际数据,分组列为Company和Ticker,代码调整如下:
# 加载实际数据 actual_df <- structure(list(Company = c("CompanyA", "CompanyA"), Ticker = c("A", "A"), Ticker_Unq = c("A1", "A2"), Description = c(NA, "Text"), Type = c("Token", NA)), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame")) # 生成合并后的新行 merged_actual <- actual_df %>% group_by(Company, Ticker) %>% filter(n() > 1) %>% summarise(across(everything(), ~ first(na.omit(.x))), .groups = "drop") %>% # 自定义新标识,可根据需求调整命名规则 mutate(Company = paste0(Company, "_New"), Ticker = paste0(Ticker, "_New")) # 合并新行到原数据 result_actual <- bind_rows(actual_df, merged_actual) print(result_actual)
关键逻辑说明
group_by():按重复标识列分组,确保只处理同一ID/公司+股票代码的行filter(n()>1):跳过无重复的行,避免不必要的处理across(everything(), ~first(na.omit(.x))):对每个列提取第一个非NA值,适用于同组内非NA值无重叠的场景bind_rows():将新生成的合并行追加到原数据框末尾
内容的提问来源于stack exchange,提问作者Soph2010
相关产品推荐
相关产品推荐

