当原DataFrame列值≤0时将对应Rank列值置为0的实现方法
问题
现有一个已完成按行数值排名的DataFrame,需求如下:
- 若原DataFrame对应位置的数值≤0,则将Rank结果中对应位置的值设为0
- 若原DataFrame对应位置的数值>0,则保留原排名数值
示例数据及当前排名代码如下,期望前两行Rank结果为:0 1 00 0 1
示例数据与代码:
# 生成示例数据框 df <- data.frame(score_1 = floor(runif(10, min=-10, max=10)), score_2 = floor(runif(10, min=-10, max=10)), score_3 = floor(runif(10, min=-10, max=10))) # 示例数据输出 score_1 score_2 score_3 1 -3 4 -7 2 0 -10 5 3 -2 -8 -8 4 -6 -6 3 5 -2 -6 -7 6 -1 -4 -4 7 -10 -7 2 8 0 7 3 9 -10 6 -1 10 9 -5 -3 # 当前生成排名的代码 rank_df <- df %>% rowwise() %>% do(data.frame(t(rank(-unlist(.))))) # 当前排名结果 score_1 score_2 score_3 1 2 1 3 2 2 3 1 3 1 2.5 2.5 4 2.5 2.5 1 5 1 2 3 6 1 2.5 2.5 7 3 2 1 8 3 1 2 9 3 1 2 10 1 3 2
解决方案
由于df和rank_df的行列结构完全匹配,可通过元素级条件判断直接修改排名结果,以下是两种高效实现方式:
方法1:dplyr 链式操作
使用mutate_all遍历所有列,结合原数据框对应列的数值做条件判断:
library(dplyr) rank_final <- rank_df %>% mutate_all(~ ifelse(df[[cur_column()]] > 0, ., 0))
方法2:矩阵式索引赋值
利用数据框的矩阵特性,通过逻辑索引直接赋值,数据量大时效率更高:
rank_final <- rank_df rank_final[df <= 0] <- 0
验证结果
执行后前两行的输出符合预期:
score_1 score_2 score_3 1 0 1 0 2 0 0 1
内容的提问来源于stack exchange,提问作者GT213
相关产品推荐
相关产品推荐

