R语言使用dplyr对分组数据跨行拼接非NA值生成新列
实现方案
dplyr方案(优先推荐)
library(dplyr) # 读入你提供的示例数据 df <- structure(list(game.event = c("279310", "279310", "279310", "279310", "279310", "279310", "279315", "279315", "279315", "279315", "279315", "279315"), L1 = c("NULL", NA, NA, NA, NA, NA, "Fade - Back Shoulder", NA, NA, NA, NA, NA), L2 = c(NA, "NULL", NA, NA, NA, NA, NA, "Curl", NA, NA, NA, NA), R2 = c(NA, NA, NA, "NULL", NA, NA, NA, NA, NA, "Out", NA, NA), R1 = c(NA, NA, "NULL", NA, NA, NA, NA, NA, "Go/Fly", NA, NA, NA), B = c(NA, NA, NA, NA, "NULL", NA, NA, NA, NA, NA, NA, "Curl")), row.names = c(NA, -12L), class = c("tbl_df", "tbl", "data.frame")) # 核心处理逻辑 df_result <- df %>% group_by(game.event) %>% mutate( # 按顺序拼接第2-6列的组内非NA值 concat_col = paste(across(2:6, ~na.omit(.x)), collapse = " ") ) %>% ungroup()
逻辑说明:
- 先按分组字段
game.event对数据分组 across(2:6)遍历第2到第6列,对每列执行na.omit()提取组内唯一的非NA值- 用
paste(collapse = " ")把提取到的5个值按列的顺序用空格拼接为字符串 - 分组状态下的
mutate会把拼接结果同步到同组所有行 - 最后用
ungroup()解除分组,避免影响后续数据操作
运行结果完全符合预期:分组279310的concat_col值为"NULL NULL NULL NULL NULL",分组279315的concat_col值为"Fade - Back Shoulder Curl Out Go/Fly Curl",同时兼容5行的少量分组场景。
可选base R方案
如果不想依赖dplyr包,可以用基础函数实现相同逻辑:
df$concat_col <- ave(seq(nrow(df)), df$game.event, FUN = function(idx) { sub_df <- df[idx, 2:6] paste(sapply(sub_df, function(col) na.omit(col)), collapse = " ") })
内容的提问来源于stack exchange,提问作者Jeff Henderson
相关产品推荐
相关产品推荐

