R语言如何按na列分组提取每组rn列最小值对应的行记录
R按分组筛选指定列最小值对应行
原始数据准备
首先构建原始数据集,注意直接用data.frame()存储可以保留列的原始类型,避免cbind()生成字符矩阵导致数值排序出错:
rn <- c(3,4,5,2,1,5,6,8,10,3,4,5,6,8,9,7) na <- c("A","A","A","A","A","B","B","B","B","B","CD","CD","CD","CD","CD","CD") mo <- c("ram","okd","mlu","lom","mpl","mpl","cdd","jjh","yyt","uu","tt","rre","llm","mm","mlp","lok") dat <- data.frame(rn, na, mo, stringsAsFactors = FALSE)
需求说明
按照na列的不同取值分组,筛选每组中rn列数值最小的完整记录,同时保留对应行的mo列取值,预期输出如下:
rn na mo 1 A mpl 3 B uu 4 CD tt
实现方案
方案1:基础R实现(无第三方包依赖)
不需要额外安装加载包,直接用R内置函数即可实现:
# 按na列分组,提取每组rn值最小的行 result <- do.call( rbind, lapply(split(dat, dat$na), function(group_df) group_df[which.min(group_df$rn), ]) ) # 调整行顺序匹配预期输出 result <- result[match(c("A","B","CD"), result$na), ] # 打印结果 print(result, row.names = FALSE)
运行输出:
rn na mo 1 A mpl 3 B uu 4 CD tt
方案2:dplyr实现(简洁流式语法)
如果日常使用tidyverse生态工具,可以用更简洁的语法实现:
library(dplyr) result <- dat %>% group_by(na) %>% # 取每组rn最小的1行,遇到并列最小值默认取第一个 slice_min(rn, n = 1, with_ties = FALSE) %>% ungroup() %>% # 调整分组顺序匹配预期 arrange(match(na, c("A","B","CD"))) print(result, row.names = FALSE)
运行后得到的结果和基础R方案完全一致。
内容的提问来源于stack exchange,提问作者Tpellirn
相关产品推荐
相关产品推荐

