如何在R中获取data.frame每行的最大值、次大值及对应列名?
提取data.frame每行最大值、次大值的列名与数值
以下是两种适配需求的实现方式:
方法一:Base R 实现
通过apply逐行处理,结合排序与列名匹配完成需求:
# 定义单行处理函数 get_top_two <- function(row) { # 按数值降序排序,同时保留原列的索引 sorted_vals <- sort(row, decreasing = TRUE, index.return = TRUE) # 拼接前两个最大值的列名与数值 first <- paste(names(row)[sorted_vals$ix[1]], sorted_vals$x[1]) second <- paste(names(row)[sorted_vals$ix[2]], sorted_vals$x[2]) return(c(firstmax = first, secondmax = second)) } # 应用函数到每行,转换为目标data.frame result_df <- as.data.frame(t(apply(example_df, 1, get_top_two)), stringsAsFactors = FALSE)
运行后result_df与你给出的desired_df完全一致。
方法二:Tidyverse 实现
通过数据重塑+分组排序实现,更适配复杂数据场景:
library(tidyverse) result_df <- example_df %>% # 添加行号用于分组 mutate(row_id = row_number()) %>% # 转换为长格式,拆分列名与数值 pivot_longer(-row_id, names_to = "colname", values_to = "value") %>% # 按行分组,按数值降序排序 group_by(row_id) %>% arrange(desc(value), .by_group = TRUE) %>% # 取每行前两个值,标记排名 slice(1:2) %>% mutate(rank = c("firstmax", "secondmax")) %>% # 拼接列名与数值 mutate(combined = paste(colname, value)) %>% # 转换回宽格式,得到目标结构 pivot_wider(id_cols = row_id, names_from = rank, values_from = combined) %>% # 移除行号列 select(-row_id) %>% ungroup()
可通过以下代码验证结果匹配度:
all.equal(result_df, desired_df) # 返回 TRUE 说明结果完全一致
内容的提问来源于stack exchange,提问作者Neal Barsch
相关产品推荐
相关产品推荐

