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

将含人员排名的DataFrame转换为按排名排序的品种列表DataFrame

按人员排名顺序整理品种列表

原始数据

我们有如下记录人员对品种排名的数据框:

df <- data.frame(
    variety = c("variety1","variety2","variety3","variety4","variety5"),
    people1 = c(1, NA, 3, 2, NA),
    people2 = c(4, 3, 2, 1, NA),
    people3 = c(3, 2, 5, 4, 1)
)

# 查看原始数据
df
#>    variety people1 people2 people3
#> 1 variety1       1       4       3
#> 2 variety2      NA       3       2
#> 3 variety3       3       2       5
#> 4 variety4       2       1       4
#> 5 variety5      NA      NA       1

需求

需要生成一个数据框,按每名人员的排名顺序(升序)列出对应品种,缺失排名的位置用<NA>填充,目标格式如下:

people1  people2  people3
1 variety1 variety4 variety5
2 variety3 variety3 variety2
3 variety4 variety2 variety1
4     <NA> variety1 variety4
5     <NA>     <NA> variety3

解决方案

方法一:基础R实现

无需额外依赖包,通过循环处理每一列:

# 获取所有人员列的列名
people_cols <- grep("people", colnames(df), value = TRUE)

# 逐个处理人员列,按排名提取品种
result_list <- lapply(people_cols, function(col) {
  # 组合品种和当前人员的排名
  temp <- df[, c("variety", col)]
  # 按排名升序排序,NA排在最后
  temp_sorted <- temp[order(temp[[col]], na.last = TRUE), ]
  # 提取品种,统一长度为5,不足的位置补NA
  out <- temp_sorted$variety
  length(out) <- nrow(df)
  out
})

# 转换为数据框并设置列名
result_df <- as.data.frame(do.call(cbind, result_list))
colnames(result_df) <- people_cols

# 查看结果
result_df

方法二:tidyverse包实现

使用dplyr和tidyr进行数据重塑:

library(tidyverse)

result_df <- df %>%
  # 宽表转长表,拆分人员和排名
  pivot_longer(cols = starts_with("people"), names_to = "person", values_to = "rank") %>%
  # 按人员分组,按排名升序排序
  group_by(person) %>%
  arrange(rank, .by_group = TRUE) %>%
  # 为每组添加行号
  mutate(row = row_number()) %>%
  # 长表转宽表,还原人员列
  pivot_wider(names_from = person, values_from = variety) %>%
  # 补全到5行,缺失位置填充NA
  complete(row = 1:nrow(df)) %>%
  # 移除行号列
  select(-row)

# 查看结果
result_df

两种方法都能得到符合要求的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:05:44