在R语言中将3个变量的和重新缩放至精确等于1的方法求助
解决方法
一、快速修正:针对误差值直接调整单列
你的自定义函数无法运行的核心问题是:直接引用全局变量df而非传入参数,且未返回修改后的数据,同时未做矢量化处理。以下是可正常运行的实现方式:
Base R 版本
# 复制原数据避免修改原始数据 df_adjusted <- df # 对sum_time为1.0001的行,给time_1减0.0001 df_adjusted$time_1[df_adjusted$sum_time == 1.0001] <- df_adjusted$time_1[df_adjusted$sum_time == 1.0001] - 0.0001 # 对sum_time为0.9999的行,给time_1加0.0001 df_adjusted$time_1[df_adjusted$sum_time == 0.9999] <- df_adjusted$time_1[df_adjusted$sum_time == 0.9999] + 0.0001 # 重新计算sum_time验证 df_adjusted$sum_time <- rowSums(df_adjusted[, c("time_1", "time_2", "time_3")])
dplyr 版本(更简洁)
library(dplyr) df_adjusted <- df %>% mutate( time_1 = case_when( sum_time == 1.0001 ~ time_1 - 0.0001, sum_time == 0.9999 ~ time_1 + 0.0001, TRUE ~ time_1 ), sum_time = rowSums(across(starts_with("time_"))) )
二、理想方案:按比例缩放保持原始占比
如果希望尽可能保留各时间项的原始比例,更合理的方式是将每行的time值除以该行的sum_time,整体缩放后和为1:
Base R 版本
# 提取所有time开头的列 time_cols <- grep("^time_", names(df), value = TRUE) # 按行缩放 df_scaled <- df df_scaled[, time_cols] <- df_scaled[, time_cols] / df_scaled$sum_time # 重新计算sum_time df_scaled$sum_time <- rowSums(df_scaled[, time_cols])
dplyr 版本
library(dplyr) df_scaled <- df %>% mutate( across(starts_with("time_"), ~ .x / sum_time), sum_time = rowSums(across(starts_with("time_"))) )
这种方式处理后,所有行的sum_time都会精确等于1,同时最大程度保留了各时间项的原始占比,比单独调整某一列更严谨。
内容的提问来源于stack exchange,提问作者Nic
相关产品推荐
相关产品推荐

