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

R语言:按列表更新列值的归一化函数报错问题求助

人口统计数据集分组归一化问题处理

需求说明

对人口统计计数数据集的相似列分组执行归一化:将分组内每列的行值除以该分组的行总和,更新对应列。例如gender组(包含male和female列),每列值需除以该行male+female的总和。

分组定义

gender <- c("male","female") 
income <- c("income_0_50k","income_50k_100k","income_over_100k")

问题代码及报错

编写的归一化函数及调用方式:

percent.total <- function(df,x){ 
  tot <- rowSums(df[x])
  for(i in 1:length(x)){
    df[x[i]] <- df[x[i]]/tot
  }
}

percent.total(dat,gender)

执行后报错:

Error in Ops.data.frame(df[x[i]], df[x]) :
‘/’ only defined for equally-sized data frames

测试情况

在函数外单独测试时,i=1可正常运行,但i=2失败:

i <- 1
tot <- rowSums(dat[gender])
dat[gender[i]] <- dat[gender[i]]/tot

样本数据

注意:样本数据包含千分位逗号,需先转换为数值型:

# 原始样本数据
dat <- data.frame(
  male = c("1,487", "726", "632", "655", "616", "1,945", "888"),
  female = c("1,501", "810", "615", "692", "599", "1,544", "980"),
  stringsAsFactors = FALSE
)
# 转换为数值型
dat$male <- as.numeric(gsub(",", "", dat$male))
dat$female <- as.numeric(gsub(",", "", dat$female))

期望输出

male    female
1 0.497657296 0.502342704
2 0.472656250 0.527343750
3 0.506816359 0.493183641
4 0.486265776 0.513734224
5 0.506995885 0.493004115
6 0.557466323 0.442533677
7 0.475374732 0.524625268

解决方案

问题原因

df[x[i]]返回的是数据框类型,而tot是向量,R中不支持数据框与向量直接做除法,这是报错的核心原因。此外,R函数默认不会修改传入的原始数据框,需返回修改后的结果。

修改后的函数(循环版)

将df[x[i]]改为df[[x[i]]](提取向量),并返回修改后的数据框:

percent.total <- function(df, x){ 
  tot <- rowSums(df[x])
  for(i in seq_along(x)){
    df[[x[i]]] <- df[[x[i]]] / tot
  }
  return(df)
}

# 调用并覆盖原数据框
dat <- percent.total(dat, gender)

更高效的向量化写法(推荐)

利用R的广播特性,无需循环直接处理整个分组列:

percent.total <- function(df, x){ 
  df[x] <- df[x] / rowSums(df[x])
  return(df)
}

# 调用
dat <- percent.total(dat, gender)

验证结果

执行上述代码后,dat将输出与期望一致的归一化结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:10:20