You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于指定行的列值重新排列R语言数据框的多列?

按数据框最后一行数值排序列(含dplyr实现方案)

问题描述

需要重新排列数据框的列:保留id列在前,其余字母命名的数值型列按最后一行的数值排序。示例数据如下:

df <- data.frame(id = c("q", "w", "e", "t", "d", "r"),
                 A=c(22, 25, 29, 13, 22, -8),
                 B=c(12, 10, 6, 6, 8, 11),
                 C=c(NA, 15, 15, 18, 22, 13),
                 D=c(90, 4, 3, 6, -6, -6))

理想输出列顺序为:id、A、D、B、C。但尝试以下代码时得到了错误的列顺序D、A、B、C、id:

neworder <- order(unlist(df[nrow(df),]))
df[, neworder]

补充要求:仅对最后一行值为数值型的字母命名列排序,排除字符型的id列。

问题原因

原代码的问题在于:

  1. 把id列也纳入了排序范围,字符型的r在排序时会被默认排在所有数值之后;
  2. 最后一行中A的值是-8,D的值是-6,升序排序时A本应在D前,你得到的反转结果可能是误操作(比如用了降序order(..., decreasing = TRUE)),但核心问题是未排除非目标列。

解决方案

1. Base R 实现

# 筛选出需要排序的数值型列(排除id)
cols_to_sort <- names(df)[sapply(df[nrow(df), ], is.numeric)]
# 提取最后一行的对应值并排序列名
sorted_cols <- cols_to_sort[order(unlist(df[nrow(df), cols_to_sort]))]
# 重新排列数据框
df_sorted <- df[, c("id", sorted_cols)]

2. dplyr 实现

无需转置数据框,直接通过select结合列名排序即可:

library(dplyr)

df_sorted <- df %>%
  # 先保留id列,再按最后一行数值排序其余数值型列
  select(
    id,
    all_of(
      # 获取除id外的数值型列名
      names(.) %>% setdiff("id") %>%
        # 按最后一行的对应值排序列名
        .[order(slice(., n()) %>% select(all_of(.)) %>% pull())]
    )
  )

执行后得到的df_sorted列顺序为id、A、D、B、C,符合需求。

内容的提问来源于stack exchange,提问作者bee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:31:23