如何批量获取dataframe各Time列最大值对应的ID与Group?
R语言:一次性获取多列最大值对应的行信息
问题描述
我有如下名为df1的dataframe:
ID Group Time1 Time2 Time3 A00194 1 0.733 0.777 0.433 A00195 1 0.903 0.116 0.308 A00198 1 0.422 0.863 0.220 A00199 1 0.485 0.846 0.203 A02111 2 0.682 0.522 0.700 A02114 2 0.699 0.208 0.686 A02116 2 0.911 0.802 0.041 A02197 2 0.083 0.082 0.900
希望获取Time1到Time3每一列最大值对应的ID、Group,同时得到最大值和对应列名(命名为Test列),期望输出如下:
ID Group Value Test A02116 2 0.911 Time1 A00198 1 0.863 Time2 A02197 2 0.900 Time3
我尝试了如下代码,但需要重复三次才能得到期望输出:
df1[which.max(df1$Time1),,c(1:4)]
请问如何一次性实现该需求?
解决方案
方法1:用tidyverse工具链(dplyr + tidyr)
先把宽格式数据转成长格式,再按列名分组取最大值对应的行:
library(tidyverse) df1 %>% pivot_longer(cols = starts_with("Time"), names_to = "Test", values_to = "Value") %>% group_by(Test) %>% filter(Value == max(Value)) %>% ungroup() %>% select(ID, Group, Value, Test) %>% arrange(Test)
步骤说明:
pivot_longer:把Time1/Time2/Time3拆成Test(列名)和Value(对应数值)两列group_by(Test):按每个Time列分组filter(Value == max(Value)):筛选出每组里数值最大的行- 最后调整列顺序并按
Test排序,得到目标结果
方法2:用Base R原生实现
不用加载额外包,通过循环处理每一列:
# 提取所有以Time开头的列名 time_cols <- grep("^Time", colnames(df1), value = TRUE) # 循环处理每一列,收集最大值对应的行信息 result_list <- lapply(time_cols, function(col) { max_row_idx <- which.max(df1[[col]]) data.frame( ID = df1$ID[max_row_idx], Group = df1$Group[max_row_idx], Value = df1[[col]][max_row_idx], Test = col, stringsAsFactors = FALSE ) }) # 合并所有结果为一个dataframe result_df <- do.call(rbind, result_list) rownames(result_df) <- NULL # 可选:移除自动生成的行名 print(result_df)
这个方法通过grep定位目标列,循环找到每列最大值的行索引,构造小数据框后合并,完全用Base R就能完成。
内容的提问来源于stack exchange,提问作者mashimena
相关产品推荐
相关产品推荐

