如何在R语言中按列值分组提取对应关联人名?
按数据框列值分组对应人名
需求说明
将数据框中a1、a2、a3列里的人名,按对应列的取值(a/b)分组,忽略NA值,最终输出每列的分组结果。
原始数据
name <- c("luis", "John", "Leo") a1 <- c("a","b","a") a2 <- c("b","a","b") a3 <- c(NA,"b","a") df <- data.frame(name,a1,a2,a3)
解决方案
方法1:基础R实现
遍历目标列,用split按列值分组人名,同时过滤NA对应的无效分组,最后整理成期望格式:
# 遍历a1到a3列 result <- lapply(df[, -1], function(col) { # 剔除NA行后,按列值分组对应人名 split(df$name[!is.na(col)], col[!is.na(col)]) }) # 按要求格式输出结果 for (col_name in names(result)) { groups <- result[[col_name]] # 把每组人名转成对应字符串格式 group_strs <- sapply(groups, function(nms) { if (length(nms) > 1) { paste0("c(\"", paste(nms, collapse = "\",\""), "\")") } else { paste0("\"", nms, "\"") } }) output_str <- paste0(names(group_strs), "=", group_strs, collapse = ", ") cat(paste0(col_name, ": ", output_str, "\n")) }
方法2:tidyverse工具包实现
先将数据转为长格式,再分组整理后输出:
library(tidyverse) df %>% pivot_longer(cols = -name, names_to = "col", values_to = "value") %>% drop_na(value) %>% group_by(col, value) %>% summarise(names = list(name), .groups = "drop") %>% group_by(col) %>% summarise(output = str_c(value, "=", ifelse(map_int(names, length) > 1, str_c("c(\"", str_c(names, collapse = "\",\""), "\")"), str_c("\"", names, "\"")), collapse = ", ")) %>% mutate(output = str_c(col, ": ", output)) %>% pull(output) %>% walk(cat, "\n")
运行结果
a1: a=c("luis","Leo"), b="John" a2: a="John", b=c("luis","Leo") a3: a="Leo", b="John"
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

