如何将数据框中每行的diam_1至diam_3值按降序重排?
实现每行数值降序排列的方法
原始数据框:
names diam_1 diam_2 diam_3 1 Adam 17 5 4 2 Bert NA 7 4 3 Charlotte 5 9 9 4 Daniel 6 3 6 5 Eleonore 9 NA 4 6 Frank 6 6 NA
目标输出(将每行
diam_1到diam_3的数值按降序重新排列):
names diam_1 diam_2 diam_3 1 Adam 17 5 4 2 Bert 7 4 NA 3 Charlotte 9 9 5 4 Daniel 6 6 3 5 Eleonore 9 4 NA 6 Frank 6 6 NA
原始数据的R结构:
structure(list(names = c("Adam", "Bert", "Charlotte", "Daniel", "Eleonore", "Frank"), diam_1 = c(17, NA, 5, 6, 9, 6), diam_2 = c(5, 7, 9, 3, NA, 6), diam_3 = c(4, 4, 9, 6, 4, NA)), class = "data.frame", row.names = c(NA, -6L))
方法1:Base R 原生实现
无需额外安装包,用apply逐行处理目标列,排序时将NA放在末尾:
# 定位所有以diam_开头的列 diam_cols <- grep("^diam_", names(df)) # 逐行对diam列降序排序,NA后置 df[diam_cols] <- t(apply(df[diam_cols], 1, function(x) sort(x, decreasing = TRUE, na.last = TRUE)))
方法2:dplyr + tidyr 管道式实现
通过数据重塑完成排序,代码可读性强:
library(dplyr) library(tidyr) df_sorted <- df %>% # 将diam列转为长格式 pivot_longer(cols = starts_with("diam_"), names_to = "diam", values_to = "value") %>% # 按姓名分组,组内按value降序排列 group_by(names) %>% arrange(desc(value), .by_group = TRUE) %>% # 重新命名diam列的序号 mutate(diam = paste0("diam_", row_number())) %>% # 转回宽格式 pivot_wider(names_from = diam, values_from = value) %>% ungroup()
方法3:data.table 高效实现
适合处理大规模数据集,逐行操作效率更高:
library(data.table) # 将data.frame转为data.table setDT(df) # 定位diam列 diam_cols <- grep("^diam_", names(df)) # 逐行排序并替换原列 df[, paste0("diam_", 1:3) := transpose(lapply(transpose(.SD), sort, decreasing = TRUE, na.last = TRUE)), .SDcols = diam_cols]
内容的提问来源于stack exchange,提问作者Gnueghoidune
相关产品推荐
相关产品推荐

