如何在R中对数据框行值进行排名并保留NA值?
保留NA值的行式排名计算(R语言)
问题背景
需要对数据框按行计算数值的排名,但要求原数据中的NA值在结果中保持为NA,而非被赋予排名。
示例数据
df = data.frame(A = c(10, 20, NA), B = c(NA, 10, 20), C = c(20, NA, 10))
原方法问题
使用默认的rank结合apply处理时,NA会被参与排名计算,无法保留:
t(apply(df, 1, rank))
输出结果:
[,1] [,2] [,3] [1,] 1 3 2 [2,] 2 1 3 [3,] 3 2 1
期望输出
[,1] [,2] [,3] [1,] 1 NA 2 [2,] 2 1 NA [3,] NA 2 1
解决方案
方法1:基础R自定义函数
自定义函数先计算排名,再将原数据中NA的位置对应设为NA:
row_rank_keep_na <- function(x) { # 计算排名,na.last="keep"暂时保留NA的位置 r <- rank(x, na.last = "keep") # 将原向量中的NA位置在排名结果中设为NA r[is.na(x)] <- NA r } # 应用到每行并转置得到结果 result <- t(apply(df, 1, row_rank_keep_na)) print(result)
方法2:tidyverse风格实现
如果习惯使用dplyr,可以用rowwise结合across处理:
library(dplyr) df %>% rowwise() %>% mutate(across(everything(), ~{ r <- rank(.x, na.last = "keep") r[is.na(.x)] <- NA r })) %>% ungroup()
两种方法都能得到符合预期的结果,核心是先计算排名,再将原数据中的NA位置在结果中还原为NA。
内容的提问来源于stack exchange,提问作者Sergei Walankov
相关产品推荐
相关产品推荐

