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

如何根据rank分组均值自动替换R数据框中的NA值

解决R语言中并列rank对应score的NA填充问题

问题背景

我们有两个数据框:

  • df_1:包含原始数据列,以及通过rank(ties.method = "average")生成的.rank列(并列值会取连续整数的均值,比如两个并列第1/2的rank值为1.5)
  • df_2:存储整数rank与对应score的映射关系

当直接将.rank列映射到df_2的score时,非整数rank会产生NA值,需要按以下规则填充:

  • 非整数rank是若干连续整数的均值,取这些整数rank对应score的均值填充NA
  • 相同的rank值必须填充相同结果

解决方案代码

1. 准备原始数据

df_1 <- data.frame(A = c(5, 6.5, 5 , 7), B = c(0.1, 0.9, 0.7, 0.01), C = c(3.5, 3.5, 1, 2), D = c(0.1, 0.5, 0.7, 0.9))
df_1$A.rank <- rank(df_1$A, ties.method = "average")
df_1$B.rank <- rank(-df_1$B, ties.method = "average")
df_1$C.rank <- rank(df_1$C, ties.method = "average")
df_1$D.rank <- rank(-df_1$D, ties.method = "average")

df_2 <- data.frame(score_rank = c(1, 2, 3, 4), score = c(0.37, 0.25, 0.2, 0.18))

2. 生成初始映射后的数据集(含NA)

new_df_1 <- df_1[, grep("\\.rank$", colnames(df_1))]
new_df_1[] <- df_2$score[match(unlist(new_df_1), df_2$score_rank)]

3. 定义rank转score的处理函数

get_score <- function(rank_val, score_df) {
  # 整数rank直接返回对应score
  if (rank_val %% 1 == 0) {
    return(score_df$score[score_df$score_rank == rank_val])
  }
  # 非整数rank:计算对应的连续整数范围
  n <- 2 / (rank_val %% 1)  # 推导并列的整数数量
  start_rank <- rank_val - (n - 1)/2
  end_rank <- rank_val + (n - 1)/2
  # 返回对应score的均值
  mean(score_df$score[score_df$score_rank %in% start_rank:end_rank])
}

4. 生成rank-score映射表并替换NA

# 提取所有唯一的rank值
unique_ranks <- unique(unlist(new_df_1))
# 批量生成映射关系
rank_score_map <- sapply(unique_ranks, get_score, score_df = df_2)
names(rank_score_map) <- unique_ranks

# 替换数据框中的所有值(包括NA)
new_df_1[] <- rank_score_map[as.character(unlist(new_df_1))]

5. 查看结果

print(new_df_1)

输出与预期一致:

A.rank B.rank C.rank D.rank
1   0.31   0.20   0.19   0.18
2   0.20   0.37   0.19   0.20
3   0.31   0.25   0.37   0.25
4   0.18   0.18   0.25   0.37

补充示例验证

当df_1的A列全为5时,A.rank会是2.5(1-4的均值),此时会自动填充df_2所有score的均值:

# 构造测试数据
df_1_test <- df_1
df_1_test$A <- rep(5, 4)
df_1_test$A.rank <- rank(df_1_test$A, ties.method = "average")

# 处理测试数据
new_df_test <- df_1_test[, grep("\\.rank$", colnames(df_1_test))]
unique_ranks_test <- unique(unlist(new_df_test))
rank_score_map_test <- sapply(unique_ranks_test, get_score, score_df = df_2)
new_df_test[] <- rank_score_map_test[as.character(unlist(new_df_test))]

print(new_df_test$A.rank)
# 输出:[1] 0.25 0.25 0.25 0.25(即(0.37+0.25+0.2+0.18)/4的结果)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:08:12